About EcommerceSearch
EcommerceSearch is an MCP server published by azsistemasdegestao in the Search category: a clean-architecture ASP.NET Core 8 Web API for searching an ecommerce product catalog, with a companion Model Context Protocol (MCP) server, integration tests, and BenchmarkDotNet benchmarks.
The repository has 2 stars and 0 forks, with the last commit 7 months ago. Six months or more without a commit doesn't mean the server is broken, but check the open issues before depending on it in production.
Install
git clone https://github.com/azsistemasdegestao/EcommerceSearchThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Tools (3)
find_similar_productsFind products similar to a reference name/phrase
Parameters not published.
get_product_by_idRetrieve a product by ID
Parameters not published.
search_productsNatural language product search
Parameters not published.
Ask AI
Ask AI about EcommerceSearch
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
EcommerceSearch
A clean-architecture ASP.NET Core 8 Web API for searching an ecommerce product catalog, with a companion Model Context Protocol (MCP) server, integration tests, and BenchmarkDotNet benchmarks.
Projects
| Project | Description |
|---|---|
EcommerceSearch.Api |
ASP.NET Core REST API — product catalog CRUD + NL search |
EcommerceSearch.McpServer |
MCP stdio server that wraps the REST API for AI tool use |
EcommerceSearch.Tests |
xUnit integration tests with in-memory SQLite |
EcommerceSearch.Benchmarks |
BenchmarkDotNet comparisons: EF Core vs Dapper |
Architecture
Client
└─▶ ProductsController (ASP.NET Core Controller)
└─▶ IProductService (Service abstraction)
├─▶ IProductRepository (EF Core reads — AsNoTracking)
└─▶ IDapperProductReadRepository (Dapper raw SQL reads)
└─▶ ProductDbContext / SQLite
Entities never leave the service layer — controllers only receive ProductDto.
Tech Stack
- .NET 8 / ASP.NET Core 8
- Entity Framework Core 8 with SQLite driver — all reads use
AsNoTracking() - Dapper 2 with
Microsoft.Data.Sqlitefor alternative read endpoints - xUnit 2 +
Microsoft.AspNetCore.Mvc.Testingfor integration tests - FluentAssertions for expressive test assertions
- BenchmarkDotNet for micro-benchmarks
- ModelContextProtocol SDK for the MCP server
Domain
Product
{
string Id // "p1" … "p100"
string Name
string Brand
string Description
decimal Price
string Category // electronics | clothing | furniture | sports | books
}
100 products are seeded at startup across 5 categories (20 each).
Getting Started
Prerequisites
Build
dotnet build EcommerceSearch.sln
Run the API
cd EcommerceSearch.Api
dotnet run
The API starts at http://localhost:5000 (HTTP) / https://localhost:5001 (HTTPS).
Swagger UI is available at http://localhost:5000/swagger in Development mode.
The SQLite database (ecommerce.db) is created and seeded automatically on first run.
Run the MCP Server
The MCP server reads the REST API base URL from appsettings.json:
{ "ApiBaseUrl": "http://localhost:5000/" }
Start the API first, then:
cd EcommerceSearch.McpServer
dotnet run
The server communicates over stdio (standard MCP transport).
Run Tests
dotnet test EcommerceSearch.Tests
Tests use an isolated in-memory SQLite database — no file is written to disk.
Run Benchmarks
cd EcommerceSearch.Benchmarks
dotnet run -c Release
API Endpoint Reference
GET /api/products/{id}
Fetch a single product by its ID.
| Parameter | Location | Type | Description |
|---|---|---|---|
id |
path | string |
Product identifier, e.g. p1 |
Responses
| Code | Description |
|---|---|
200 OK |
ProductDto |
404 Not Found |
Product does not exist |
Example
curl http://localhost:5000/api/products/p1
GET /api/products
Paginated product list via EF Core.
| Parameter | Location | Type | Default | Description |
|---|---|---|---|---|
category |
query | string |
— | Filter by category (case-insensitive) |
page |
query | int |
1 |
Page number (1-based) |
pageSize |
query | int |
20 |
Items per page (max 100) |
Response — PagedResult<ProductDto>
Example
curl "http://localhost:5000/api/products?category=electronics&page=1&pageSize=10"
GET /api/products/dapper
Same paginated list but executed with raw SQL via Dapper.
| Parameter | Location | Type | Default | Description |
|---|---|---|---|---|
category |
query | string |
— | Filter by category |
page |
query | int |
1 |
Page number |
pageSize |
query | int |
20 |
Items per page (max 100) |
Example
curl "http://localhost:5000/api/products/dapper?category=clothing&page=2&pageSize=5"
POST /api/products/search
Natural language product search — parses a free-text query into structured filters.
Request body
{
"query": "show me electronics under 500",
"page": 1,
"pageSize": 20
}
Response — PagedResult<ProductDto>
Supported filter patterns
| Intent | Example phrases |
|---|---|
| Category | "electronics", "clothing", "furniture", "sports", "books" |
| Brand | Any capitalized word not in the stop-word list, e.g. "Nike", "Samsung" |
| Max price | "under 100", "below 50", "less than 200", "max 300" |
| Similarity | "similar to iPhone 14", "similar to MacBook Pro" |
Filters combine: only products matching all parsed filters are returned.
Natural Language Search Examples
# Electronics under $500
curl -X POST http://localhost:5000/api/products/search \
-H "Content-Type: application/json" \
-d '{"query": "show me electronics under 500", "page": 1, "pageSize": 20}'
# Nike shoes below $200
curl -X POST http://localhost:5000/api/products/search \
-H "Content-Type: application/json" \
-d '{"query": "Nike shoes below 200"}'
# Similar to MacBook Pro
curl -X POST http://localhost:5000/api/products/search \
-H "Content-Type: application/json" \
-d '{"query": "similar to MacBook Pro"}'
# Samsung furniture
curl -X POST http://localhost:5000/api/products/search \
-H "Content-Type: application/json" \
-d '{"query": "Samsung furniture"}'
# Cheap books
curl -X POST http://localhost:5000/api/products/search \
-H "Content-Type: application/json" \
-d '{"query": "books under 20"}'
Rate Limiting
Per-IP fixed-window rate limiting:
| Setting | Default |
|---|---|
| Permit limit | 30 requests |
| Window | 60 seconds |
| Queue limit | 5 requests |
Requests that exceed the limit and queue receive 429 Too Many Requests.
Configure in appsettings.json:
{
"RateLimit": {
"PermitLimit": 30,
"WindowSeconds": 60,
"QueueLimit": 5
}
}
MCP Tools
The EcommerceSearch.McpServer exposes three tools to AI agents:
| Tool | Description |
|---|---|
get_product_by_id |
Retrieve a product by ID |
search_products |
Natural language product search |
find_similar_products |
Find products similar to a reference name/phrase |
The MCP server never accesses the database directly — it calls the REST API over HTTP.
Project Structure
EcommerceSearch/
├── EcommerceSearch.Api/
│ ├── Controllers/
│ │ └── ProductsController.cs # GET /{id}, GET /, GET /dapper, POST /search
│ ├── Services/
│ │ ├── IProductService.cs
│ │ └── ProductService.cs # NL query parser + business logic
│ ├── Data/
│ │ ├── ProductDbContext.cs
│ │ ├── IProductRepository.cs
│ │ ├── EfProductRepository.cs # EF Core + AsNoTracking
│ │ ├── IDapperProductReadRepository.cs
│ │ ├── DapperProductReadRepository.cs
│ │ └── ProductSeeder.cs # 100 seed products
│ ├── Contracts/
│ │ ├── ProductDto.cs
│ │ ├── PagedResult.cs
│ │ ├── ProductSearchFilters.cs
│ │ └── SearchProductsRequest.cs
│ ├── Models/
│ │ └── Product.cs
│ ├── Filters/
│ │ ├── GlobalActionLoggerAsync.cs # Request/response timing
│ │ └── GlobalExceptionHandlingFilter.cs # ProblemDetails error responses
│ ├── Options/
│ │ └── RateLimitOptions.cs
│ └── Program.cs
├── EcommerceSearch.McpServer/
│ ├── Clients/
│ │ └── ProductApiClient.cs # Typed HTTP client for the REST API
│ ├── Models/
│ │ ├── ProductDto.cs
│ │ └── PagedResult.cs
│ ├── Tools/
│ │ └── ProductTools.cs # MCP tool definitions
│ └── Program.cs
├── EcommerceSearch.Tests/
│ ├── CustomWebApplicationFactory.cs # In-memory SQLite, no file I/O
│ ├── ProductsControllerTests.cs
│ ├── ProductDapperTests.cs
│ ├── NaturalLanguageSearchTests.cs
│ ├── RateLimitingTests.cs
│ └── GlobalExceptionHandlingFilterTests.cs
├── EcommerceSearch.Benchmarks/
│ ├── ProductCategoryQueryBenchmark.cs
│ └── Program.cs
└── EcommerceSearch.sln
Coding Conventions
- All identifiers and comments in English
- Interfaces prefixed with
I(e.g.IProductService) - EF Core implementations suffixed with
Ef(e.g.EfProductRepository) - Controllers are plural (
ProductsController) - DTOs suffixed with
Dto(ProductDto) - Raw entities never leave the service layer — always mapped to DTOs
- Exception handling centralised in
GlobalExceptionHandlingFilter - Logging centralised in
GlobalActionLoggerAsync
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.