Skip to content

Commit 03fb871

Browse files
committed
Implement Model Context Protocol (MCP) service with tools and prompts management
- Added IMcpService interface defining core MCP methods for tools and prompts. - Implemented McpService class with methods for listing tools, listing prompts, calling tools, and processing NLWeb queries. - Created MCP models including McpTool, McpPrompt, and related response/request classes. - Developed unit tests for McpService to ensure functionality of tools and prompts. - Introduced TestNLWebService for mocking INLWebService in tests. - Updated NLWebNet.Tests project to include NSubstitute for mocking dependencies.
1 parent 2a229db commit 03fb871

File tree

8 files changed

+1152
-17
lines changed

8 files changed

+1152
-17
lines changed

doc/todo.md

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@ The demo application is now fully functional with a modern .NET 9 Blazor Web App
5454
-**Business Logic Layer**: Complete implementation of core services (INLWebService, IQueryProcessor, IResultGenerator, IDataBackend) with Microsoft.Extensions.AI integration
5555
-**Comprehensive Testing**: Added MSTest unit tests for QueryProcessor and MockDataBackend (11 tests, 100% pass rate)
5656
-**Testing Framework Migration**: Migrated from xUnit to MSTest 3.9.3 with code coverage support and .NET 9 compatibility
57+
-**Mocking Library**: Uses NSubstitute 5.3.0 for clean, fluent mock setup and verification in unit tests
5758
-**Package Compatibility**: Ensured all dependencies are stable .NET 9 compatible versions (except ModelContextProtocol which is appropriately in preview)
5859
-**CI/CD Stability**: Fixed GitHub Actions workflow permissions, removed invalid parameters, and verified YAML formatting
5960
-**CI/CD Optimization**: Added smart build skipping for markdown-only changes to save CI/CD resources and time
61+
-**MCP Integration**: Complete Model Context Protocol implementation with 2 tools, 3 prompts, comprehensive testing (13 new tests, 24 total)
6062
-**Production Ready**: All builds (Debug/Release) work correctly, demo app runs successfully at <http://localhost:5038>
6163

6264
The project is now ready for Phase 4 (MCP Integration) with a solid foundation of tested, extensible business logic.
@@ -139,17 +141,53 @@ The core business logic layer has been successfully implemented with the followi
139141
- MockDataBackend provides realistic sample data with relevance scoring for demo purposes
140142
- **Testing Framework**: Uses MSTest 3.2.0 with Microsoft.Testing.Extensions.CodeCoverage for comprehensive unit testing
141143

142-
### Phase 4: MCP Integration (Library)
143-
144-
- [ ] Implement MCP core methods in `/src/NLWebNet/MCP/`:
145-
- [ ] `IMcpService` interface
146-
- [ ] `McpService` implementation
147-
- [ ] `list_tools` endpoint handler
148-
- [ ] `list_prompts` endpoint handler
149-
- [ ] `call_tool` endpoint handler
150-
- [ ] `get_prompt` endpoint handler
151-
- [ ] Create MCP-specific response formatters
152-
- [ ] **OPEN QUESTION**: What tools and prompts should be exposed via MCP?
144+
### Phase 4: MCP Integration (Library) ✅
145+
146+
#### Status: Complete
147+
148+
The Model Context Protocol (MCP) integration has been successfully implemented with full tool and prompt support:
149+
150+
- [x] **MCP Core Implementation**:
151+
- [x] `IMcpService` interface with comprehensive MCP method definitions
152+
- [x] `McpService` implementation with full functionality
153+
- [x] Complete MCP request/response models (`McpModels.cs`)
154+
- [x] Registration in dependency injection container
155+
- [x] **MCP Tool Endpoints**:
156+
- [x] `list_tools` endpoint handler returning 2 tools:
157+
- `nlweb_search`: Basic NLWeb search with mode support (list, summarize, generate)
158+
- `nlweb_query_history`: Contextual search using conversation history
159+
- [x] `call_tool` endpoint handler with proper argument processing and error handling
160+
- [x] JSON schema definitions for tool input validation
161+
- [x] **MCP Prompt Endpoints**:
162+
- [x] `list_prompts` endpoint handler returning 3 prompts:
163+
- `nlweb_search_prompt`: Structured search query generation
164+
- `nlweb_summarize_prompt`: Result summarization prompts
165+
- `nlweb_generate_prompt`: Comprehensive answer generation prompts
166+
- [x] `get_prompt` endpoint handler with template argument substitution
167+
- [x] **Integration Features**:
168+
- [x] Full integration with existing `INLWebService` for query processing
169+
- [x] MCP-specific response formatting for AI client consumption
170+
- [x] Support for streaming and non-streaming responses
171+
- [x] Proper error handling and validation
172+
- [x] Context-aware query processing with conversation history
173+
- [x] **Comprehensive Testing**: Added 13 MSTest unit tests covering all MCP functionality:
174+
- Tool listing and validation
175+
- Prompt listing and template processing
176+
- Tool calling with various argument combinations
177+
- Error handling for invalid tools/prompts/arguments
178+
- Integration with NLWebService
179+
- Null argument validation
180+
- [x] **Testing with NSubstitute**: All MCP tests use NSubstitute 5.3.0 for clean mock setup and verification
181+
182+
#### Technical Implementation
183+
184+
- **Tools Exposed**: `nlweb_search` and `nlweb_query_history` with comprehensive JSON schemas
185+
- **Prompts Exposed**: Search, summarize, and generate prompts with configurable arguments
186+
- **Error Handling**: Graceful fallbacks with detailed error messages for AI clients
187+
- **Type Safety**: Full nullable reference type support and comprehensive validation
188+
- **Testing**: 100% test coverage with 24/24 tests passing (11 existing + 13 new MCP tests)
189+
190+
The MCP integration provides a complete interface for AI clients to interact with NLWeb functionality through standardized tool calls and prompt templates.
153191

154192
### Phase 5: API Controllers & Middleware (Library)
155193

src/NLWebNet/Extensions/ServiceCollectionExtensions.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.Extensions.DependencyInjection;
22
using NLWebNet.Models;
33
using NLWebNet.Services;
4+
using NLWebNet.MCP;
45

56
namespace NLWebNet;
67

@@ -21,13 +22,14 @@ public static IServiceCollection AddNLWebNet(this IServiceCollection services, A
2122
if (configureOptions != null)
2223
{
2324
services.Configure(configureOptions);
24-
}
25-
26-
// Register core NLWebNet services
25+
} // Register core NLWebNet services
2726
services.AddScoped<INLWebService, NLWebService>();
2827
services.AddScoped<IQueryProcessor, QueryProcessor>();
2928
services.AddScoped<IResultGenerator, ResultGenerator>();
3029

30+
// Register MCP services
31+
services.AddScoped<IMcpService, McpService>();
32+
3133
// Register default data backend (can be overridden)
3234
services.AddScoped<IDataBackend, MockDataBackend>();
3335

src/NLWebNet/MCP/IMcpService.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System.Collections.Generic;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using NLWebNet.Models;
5+
6+
namespace NLWebNet.MCP;
7+
8+
/// <summary>
9+
/// Interface for Model Context Protocol (MCP) service implementation.
10+
/// Provides core MCP methods for tools and prompts management.
11+
/// </summary>
12+
public interface IMcpService
13+
{
14+
/// <summary>
15+
/// Lists all available tools that can be called via MCP.
16+
/// </summary>
17+
/// <param name="cancellationToken">Cancellation token for the operation.</param>
18+
/// <returns>Collection of available tools with their metadata.</returns>
19+
Task<McpListToolsResponse> ListToolsAsync(CancellationToken cancellationToken = default);
20+
21+
/// <summary>
22+
/// Lists all available prompts that can be retrieved via MCP.
23+
/// </summary>
24+
/// <param name="cancellationToken">Cancellation token for the operation.</param>
25+
/// <returns>Collection of available prompts with their metadata.</returns>
26+
Task<McpListPromptsResponse> ListPromptsAsync(CancellationToken cancellationToken = default);
27+
28+
/// <summary>
29+
/// Calls a specific tool with the provided arguments.
30+
/// </summary>
31+
/// <param name="request">Tool call request containing tool name and arguments.</param>
32+
/// <param name="cancellationToken">Cancellation token for the operation.</param>
33+
/// <returns>Tool execution result.</returns>
34+
Task<McpCallToolResponse> CallToolAsync(McpCallToolRequest request, CancellationToken cancellationToken = default);
35+
36+
/// <summary>
37+
/// Retrieves a specific prompt with optional argument substitution.
38+
/// </summary>
39+
/// <param name="request">Prompt request containing prompt name and arguments.</param>
40+
/// <param name="cancellationToken">Cancellation token for the operation.</param>
41+
/// <returns>Prompt content with substituted arguments.</returns>
42+
Task<McpGetPromptResponse> GetPromptAsync(McpGetPromptRequest request, CancellationToken cancellationToken = default);
43+
44+
/// <summary>
45+
/// Processes an NLWeb query and returns the response in MCP format.
46+
/// </summary>
47+
/// <param name="request">NLWeb request to process.</param>
48+
/// <param name="cancellationToken">Cancellation token for the operation.</param>
49+
/// <returns>NLWeb response formatted for MCP consumption.</returns>
50+
Task<NLWebResponse> ProcessNLWebQueryAsync(NLWebRequest request, CancellationToken cancellationToken = default);
51+
}

0 commit comments

Comments
 (0)