Content
# Event Management API
[](https://github.com/albonidrizi/Event-Management-API/actions/workflows/ci.yml)
[](https://openjdk.org/)
[](MCP.md)
[](LICENSE)
Event-management backend with two first-class interfaces: a JAX-RS REST API for applications and a Model Context Protocol server for AI clients. Both interfaces reuse the same validation, transactions, services, JDBC repositories, and MySQL data.
## Why This Project Stands Out
- One domain exposed through REST, local MCP stdio, and remote MCP Streamable HTTP.
- `32` MCP tools, `7` resources, and `8` parameterized resource templates.
- Real business workflows: capacity checks, transactional bulk registration, cancellation, check-in, audit logs, status history, pagination, reporting, and CSV export.
- No ORM: SQL, joins, aggregations, transactions, and repository boundaries are explicit.
- Reproducible setup with Docker Compose, Maven Wrapper, seeded MySQL, CI, and integration tests with a `60%` line-coverage gate.
- Safe-by-default configuration: no committed database password and guarded remote MCP binding.
## Stack
- Java 17+
- Jersey / JAX-RS
- Apache Tomcat 9
- JDBC
- MySQL
- Maven
- JSON request/response bodies
- Model Context Protocol server over stdio
- No ORM
## Architecture
```mermaid
flowchart LR
App["REST clients"] --> REST["JAX-RS resources"]
AI["Gemini / Claude / Copilot / ChatGPT"] --> MCP["MCP stdio or HTTP"]
REST --> Service["Shared services and business rules"]
MCP --> Service
Service --> Repo["JDBC repositories"]
Repo --> DB[("MySQL")]
```
REST and MCP run as separate processes, but they reuse the same business logic, validation, transactions, repositories, and MySQL database.
Packages:
```text
config JAX-RS, Jackson, database connection config
model Entity models and status enums
dto Request/response DTOs
resource REST endpoints
mcp MCP server, tools, resources, and resource templates
service Business logic, validation, transactions
repository JDBC SQL access
exception JSON error handling
```
## Main Business Modules
- Event categories
- Events
- Participants
- Event registrations
- Check-in flow
- Registration summary reports
## Quick Start With Docker
Requirements: Docker Desktop and Git.
```bash
cp .env.example .env
# Replace every placeholder in .env, then:
docker compose up --build
```
Verify the REST API:
```text
GET http://localhost:8081/event-management-api/api/events/health
```
Run the optional protected MCP HTTP container too:
```bash
docker compose --profile mcp-http up --build
```
The MCP endpoint is `http://localhost:8090/mcp` and requires the Bearer token configured in `.env`.
## Database Setup
Database URL and username have local defaults. The password is intentionally required and must be supplied outside Git:
```text
DB_URL=jdbc:mysql://localhost:3306/event_management?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
DB_USERNAME=root
DB_PASSWORD=your-local-password
```
You can override these with environment variables or JVM system properties:
```text
-Devent.db.url=jdbc:mysql://localhost:3306/event_management?useSSL=false&serverTimezone=UTC
-Devent.db.username=root
-Devent.db.password=your_password
```
Create the database:
```sql
CREATE DATABASE event_management;
USE event_management;
```
Then run:
```text
src/main/resources/schema.sql
```
Optional sample data:
```text
src/main/resources/seed-data.sql
```
The schema includes primary keys, foreign keys, unique constraints, indexes, soft delete flags, and audit columns.
It also includes extension tables for registration status history and audit logs.
## Build
```bash
./mvnw clean package
```
Outputs:
```text
target/event-management-api.war
target/event-management-mcp.jar
target/event-management-mcp-http.jar
```
## MCP Server
The project includes an executable Model Context Protocol server built with the official Java MCP SDK and the `stdio` transport.
It exposes:
- `32` tools for reading and changing event-management data
- `7` static read-only resources
- `8` parameterized resource templates
- CRUD operations for categories, participants, events, and registrations
- Registration, bulk registration, cancellation, check-in, reports, CSV export, status history, and audit logs
MCP resources are read-only. MCP tools can read, create, update, and delete data.
Two MCP transports are available:
- `event-management-mcp.jar`: local stdio transport for Gemini CLI and similar clients
- `event-management-mcp-http.jar`: Streamable HTTP transport for ChatGPT and remote MCP clients
The stdio server is tested with Gemini CLI, Claude Code, and GitHub Copilot in VS Code.
Build both the REST API and MCP server:
```bash
./mvnw clean package
```
Normally, an MCP client starts the server automatically using:
```bash
java -jar target/event-management-mcp.jar
```
### Connect Gemini CLI
Register the MCP server from the project directory:
```bash
gemini mcp add --scope project --transport stdio --timeout 30000 event-management java -- -jar "C:\absolute\path\to\target\event-management-mcp.jar"
```
Verify the connection:
```bash
gemini mcp list
```
Expected status:
```text
event-management - Connected
```
Example prompts:
```text
List all active participants using event-management MCP.
Create a category named Music using event-management MCP.
Show the registration summary for event ID 1.
```
### Connect ChatGPT
Start the Streamable HTTP server:
```bash
java -jar target/event-management-mcp-http.jar
```
It listens on:
```text
http://127.0.0.1:8090/mcp
```
Expose it temporarily over HTTPS:
```bash
ngrok http 8090
```
In ChatGPT, enable developer mode, create a custom app/connector, and use:
```text
https://your-ngrok-domain.ngrok.app/mcp
```
Localhost mode can run without authentication. Set `MCP_HTTP_BEARER_TOKEN` to protect compatible clients. The server refuses to bind outside localhost without a token unless `MCP_HTTP_ALLOW_INSECURE_REMOTE=true` is explicitly set for a temporary test-data demo. A production deployment should use stable HTTPS and OAuth 2.1.
### Connect Claude Code
```bash
claude mcp add --transport stdio --scope local event-management -- java -jar target/event-management-mcp.jar
claude mcp list
```
### Connect GitHub Copilot
The included `.vscode/mcp.json` configures the local stdio server. In VS Code, open Copilot Chat, select `Agent`, and enable `event-management` from the tools picker.
Full MCP setup, client configuration, tools, and resources are documented in:
```text
MCP.md
```
## Run Locally
REST and MCP do not require one shared process:
- Run REST with Maven Cargo when testing HTTP endpoints.
- Gemini CLI or another MCP client starts the MCP JAR when it needs MCP tools.
- Both processes connect directly to the same MySQL database.
With embedded Tomcat 9 through Maven Cargo:
```bash
./mvnw package cargo:run
```
The project is configured for port `8081`.
Health check:
```text
GET http://localhost:8081/event-management-api/api/events/health
```
Response:
```json
{
"status": "API is running"
}
```
MCP health prompt:
```text
Use event-management MCP to check the server health.
```
## Verification
Run the automated tests:
```bash
./mvnw verify
```
The integration tests verify MCP initialization over stdio and Streamable HTTP, Bearer token protection, complete write lifecycles, all read tools and resources, parameterized resources, concurrent tool calls, database row counts, and clean shutdown after the stdio client disconnects. CI runs the same verification against a real MySQL service, enforces at least `60%` line coverage, and publishes the JaCoCo report as an artifact.
For a quick REST walkthrough after startup:
```powershell
./scripts/demo-rest.ps1
```
## Deploy to Tomcat
1. Install Apache Tomcat 9.
2. Build with `mvn clean package`.
3. Copy `target/event-management-api.war` to Tomcat `webapps`.
4. Start Tomcat.
5. Use:
```text
http://localhost:8080/event-management-api/api/events/health
```
Use Tomcat 9, not Tomcat 10, because this project uses `javax.ws.rs` and Servlet 4.
## Error Format
All handled errors return JSON:
```json
{
"errorCode": "VALIDATION_ERROR",
"message": "capacity must be greater than 0"
}
```
Common status codes:
- `400 Bad Request`: validation errors
- `404 Not Found`: missing entity
- `409 Conflict`: business conflict, duplicate registration, full event
- `500 Internal Server Error`: unexpected failure
## Status Values
Event status:
```text
ACTIVE
CANCELLED
COMPLETED
```
Registration status:
```text
REGISTERED
CANCELLED
ATTENDED
```
## Endpoints
### Event Categories CRUD
```text
GET /api/event-categories
GET /api/event-categories/{id}
POST /api/event-categories
PUT /api/event-categories/{id}
DELETE /api/event-categories/{id}
```
### Events CRUD
```text
GET /api/events
GET /api/events?status=ACTIVE
GET /api/events?categoryId=1
GET /api/events/{id}
POST /api/events
PUT /api/events/{id}
DELETE /api/events/{id}
```
### Participants CRUD
```text
GET /api/participants
GET /api/participants/{id}
POST /api/participants
PUT /api/participants/{id}
DELETE /api/participants/{id}
```
### Registrations CRUD
```text
GET /api/registrations
GET /api/registrations/{id}
POST /api/registrations
PUT /api/registrations/{id}
DELETE /api/registrations/{id}
```
### Business Endpoints
```text
POST /api/events/{id}/register
POST /api/events/{id}/register-bulk
POST /api/events/{id}/cancel-registration
POST /api/registrations/{id}/check-in
GET /api/registrations/{id}/status-history
GET /api/events/{id}/participants
GET /api/events/{id}/participants/export
GET /api/events/available
GET /api/events/search?search=java&page=1&size=10
GET /api/events/{id}/registration-summary
GET /api/audit-logs
```
### Extensions Added
- Status history: `registration_status_history` stores old and new registration statuses.
- Pagination and search: `GET /api/events/search` supports `search`, `status`, `categoryId`, `page`, and `size`.
- Audit table: `audit_log` records registration actions such as register, bulk register, cancel, and check-in.
- CSV export: `GET /api/events/{id}/participants/export` returns participants as `text/csv`.
- Bulk operation: `POST /api/events/{id}/register-bulk` registers multiple participants in one transaction.
## Business Endpoint Design
Full endpoint-by-endpoint business design is documented in:
```text
BUSINESS_DESIGN.md
```
`POST /api/events/{id}/register`
Purpose: registers a participant for an active event if capacity is available.
Request:
```json
{
"participantId": 1
}
```
Validation:
- Event must exist.
- Participant must exist.
- Event status must be `ACTIVE`.
- Event date must not be in the past.
- Participant must not already be registered.
- Capacity must not be full.
Processing:
- Opens a JDBC transaction.
- Reads event and participant.
- Checks existing registration and capacity.
- Inserts `event_registration`.
- Commits or rolls back.
Failure cases:
- `400` missing participantId
- `404` event or participant missing
- `409` duplicate registration or full event
`POST /api/registrations/{id}/check-in`
Purpose: marks a registered participant as attended.
Validation:
- Registration must exist.
- Cancelled registration cannot be checked in.
- Already attended registration returns conflict.
Processing:
- Opens a transaction.
- Reads registration.
- Updates status to `ATTENDED`.
- Commits or rolls back.
`GET /api/events/{id}/participants`
Purpose: lists participants registered for an event.
SQL concept: uses `JOIN` between `event_registration` and `participant`.
`GET /api/events/{id}/registration-summary`
Purpose: returns capacity, registered, attended, cancelled, and remaining seats.
SQL concept: uses `SUM(CASE ...)`, `GROUP BY`, and calculated remaining capacity.
The implementation also includes `COUNT` and `AVG` in this summary query.
Example response:
```json
{
"eventId": 1,
"eventTitle": "Java Backend Workshop",
"capacity": 40,
"totalRegistrations": 22,
"registered": 12,
"attended": 8,
"cancelled": 2,
"remaining": 28,
"attendanceRate": 0.36
}
```
## Example Requests
Use:
```text
src/main/resources/api-examples.http
```
or import the same URLs manually in Postman or Charles.
## Project Documents
- [MCP.md](MCP.md): transports, clients, capabilities, and security settings
- [BUSINESS_DESIGN.md](BUSINESS_DESIGN.md): endpoint-by-endpoint business rules
- [CONTRIBUTING.md](CONTRIBUTING.md): contributor setup and workflow
- [SECURITY.md](SECURITY.md): security policy and deployment boundaries
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
firecrawl
Firecrawl MCP Server enables web scraping, crawling, and content extraction.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers