Skip to content

Commit e64bc4e

Browse files
committed
Update README and MCP doc
1 parent 89dc65e commit e64bc4e

File tree

2 files changed

+226
-18
lines changed

2 files changed

+226
-18
lines changed

README.md

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=nanoframework_lib-nanoframework.WebServer&metric=alert_status)](https://sonarcloud.io/dashboard?id=nanoframework_lib-nanoframework.WebServer) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=nanoframework_lib-nanoframework.WebServer&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=nanoframework_lib-nanoframework.WebServer) [![NuGet](https://img.shields.io/nuget/dt/nanoFramework.WebServer.svg?label=NuGet&style=flat&logo=nuget)](https://www.nuget.org/packages/nanoFramework.WebServer/) [![#yourfirstpr](https://img.shields.io/badge/first--timers--only-friendly-blue.svg)](https://github.com/nanoframework/Home/blob/main/CONTRIBUTING.md) [![Discord](https://img.shields.io/discord/478725473862549535.svg?logo=discord&logoColor=white&label=Discord&color=7289DA)](https://discord.gg/gCyBu8T)
1+
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=nanoframework_lib-nanoframework.WebServer&metric=alert_status)](https://sonarcloud.io/dashboard?id=nanoframework_lib-nanoframework.WebServer) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=nanoframework_lib-nanoframework.WebServer&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=nanoframework_lib-nanoframework.WebServer) [![NuGet](https://img.shields.io/nuget/dt/nanoFramework.WebServer.svg?label=NuGet&style=flat&logo=nuget)](https://www.nuget.org/packages/nanoFramework.WebServer/) [![#yourfirstpr](https://img.shields.io/badge/first--timers--only-friendly-blue.svg)](https://github.com/nanoframework/Home/blob/main/CONTRIBUTING.md) [![Discord](https://img.shields.io/discord/478725473862549535.svg?logo=discord&logoColor=white&label=Discord&color=7289DA)](https://discord.gg/gCyBu8T)
22

33
![nanoFramework logo](https://raw.githubusercontent.com/nanoframework/Home/main/resources/logo/nanoFramework-repo-logo.png)
44

@@ -35,7 +35,7 @@ This library provides a lightweight, multi-threaded HTTP/HTTPS WebServer for .NE
3535

3636
Using the Web Server is very straight forward and supports event based calls.
3737

38-
```csharp
38+
'''csharp
3939
// You need to be connected to a wifi or ethernet connection with a proper IP Address
4040

4141
using (WebServer server = new WebServer(80, HttpProtocol.Http))
@@ -56,13 +56,13 @@ private static void ServerCommandReceived(object source, WebServerEventArgs e)
5656
WebServer.OutputHttpCode(e.Context.Response, HttpStatusCode.NotFound);
5757
}
5858
}
59-
```
59+
'''
6060

6161
### Controller-Based WebServer
6262

63-
Controllers are supported including with parametarized routes like `api/led/{id}/dosomething/{order}`.
63+
Controllers are supported including with parametarized routes like 'api/led/{id}/dosomething/{order}'.
6464

65-
```csharp
65+
'''csharp
6666
using (WebServer server = new WebServer(80, HttpProtocol.Http, new Type[] { typeof(MyController) }))
6767
{
6868
server.Start();
@@ -86,15 +86,15 @@ public class MyController
8686
WebServer.OutPutStream(e.Context.Response, $"You selected Led {ledId}!");
8787
}
8888
}
89-
```
89+
'''
9090

9191
## Model Context Protocol (MCP) Support
9292

9393
Enable AI agents to interact with your embedded devices through standardized tools and JSON-RPC 2.0 protocol.
9494

9595
### Defining MCP Tools
9696

97-
```csharp
97+
'''csharp
9898
public class IoTTools
9999
{
100100
[McpServerTool("read_sensor", "Reads temperature from sensor")]
@@ -117,18 +117,45 @@ public class LedCommand
117117
[Description("LED state: on, off, or blink")]
118118
public string State { get; set; }
119119
}
120+
'''
121+
122+
### Defining MCP Prompts
123+
124+
You can define reusable, high-level prompts for AI agents using the `McpServerPrompt` attribute. Prompts encapsulate multi-step instructions or workflows that can be invoked by agents.
125+
126+
Here's a simple example:
127+
128+
```csharp
129+
using nanoFramework.WebServer.Mcp;
130+
131+
public class McpPrompts
132+
{
133+
[McpServerPrompt("echo_sanity_check", "Echo test prompt")]
134+
public static PromptMessage[] EchoSanityCheck()
135+
{
136+
return new PromptMessage[]
137+
{
138+
new PromptMessage("Call Echo with the string 'Hello MCP world!' and return the response.")
139+
};
140+
}
141+
}
120142
```
121143

144+
Prompts can be discovered and invoked by AI agents in the same way as tools. You can also define prompts with parameters using the `McpPromptParameter` attribute.
145+
122146
### Setting Up MCP Server
123147

124-
```csharp
148+
'''csharp
125149
public static void Main()
126150
{
127151
// Connect to WiFi first
128152
var connected = WifiNetworkHelper.ConnectDhcp(Ssid, Password, requiresDateTime: true);
129153

130154
// Discover and register MCP tools
131155
McpToolRegistry.DiscoverTools(new Type[] { typeof(IoTTools) });
156+
157+
// Discover and register MCP prompts
158+
McpPromptRegistry.DiscoverPrompts(new Type[] { typeof(McpPrompts) });
132159

133160
// Start WebServer with MCP support
134161
using (var server = new WebServer(80, HttpProtocol.Http, new Type[] { typeof(McpServerController) }))
@@ -141,13 +168,13 @@ public static void Main()
141168
Thread.Sleep(Timeout.Infinite);
142169
}
143170
}
144-
```
171+
'''
145172

146173
### AI Agent Integration
147174

148175
Once running, AI agents can discover and invoke your tools:
149176

150-
```json
177+
'''json
151178
// Tool discovery
152179
POST /mcp
153180
{
@@ -167,7 +194,7 @@ POST /mcp
167194
},
168195
"id": 2
169196
}
170-
```
197+
'''
171198

172199
## Documentation
173200

@@ -187,11 +214,12 @@ POST /mcp
187214
- No compression support in request/response streams
188215
- MCP implementation supports server features only (no notifications or SSE)
189216
- No or single parameter limitation for MCP tools (use complex objects for multiple parameters)
217+
- Prompt parameters, when declared, are always mandatory.
190218

191219
## Installation
192220

193-
Install `nanoFramework.WebServer` for the Web Server without File System support. Install `nanoFramework.WebServer.FileSystem` for file serving, so with devices supporting File System.
194-
Install `nanoFramework.WebServer.Mcp` for MCP support. It does contains the full `nanoFramework.WebServer` but does not include native file serving. You can add this feature fairly easilly by reusing the code function serving it.
221+
Install 'nanoFramework.WebServer' for the Web Server without File System support. Install 'nanoFramework.WebServer.FileSystem' for file serving, so with devices supporting File System.
222+
Install 'nanoFramework.WebServer.Mcp' for MCP support. It does contains the full 'nanoFramework.WebServer' but does not include native file serving. You can add this feature fairly easilly by reusing the code function serving it.
195223

196224
## Contributing
197225

doc/model-context-protocol.md

Lines changed: 185 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,50 @@ The Model Context Protocol (MCP) is an open standard that enables seamless integ
2727

2828
### Key Features
2929

30-
- **Automatic tool discovery** through reflection and attributes
30+
- **Automatic tool and prompt discovery** through reflection and attributes
31+
- **MCP Prompts**: Define reusable, high-level prompt workflows for AI agents, with support for parameters
3132
- **JSON-RPC 2.0 compliant** request/response handling
3233
- **Type-safe parameter handling** with automatic deserialization from JSON to .NET objects
3334
- **Flexible authentication** options (none, basic auth, API key)
3435
- **Complex object support** for both input parameters and return values
3536
- **Robust error handling** and validation
3637
- **Memory efficient** implementation optimized for embedded devices
3738
- **HTTPS support** with SSL/TLS encryption
39+
## Defining MCP Prompts
40+
41+
MCP Prompts allow you to define reusable, multi-step instructions or workflows that can be invoked by AI agents. Prompts are discovered and registered similarly to tools, using the `[McpServerPrompt]` attribute on static methods that return an array of `PromptMessage`.
42+
43+
Prompts can encapsulate complex logic, multi-step flows, or provide high-level instructions for agents. You can also define parameters for prompts using the `[McpPromptParameter]` attribute. **All parameters defined for a prompt are mandatory.**
44+
45+
### Example: Defining a Prompt
46+
47+
```csharp
48+
using nanoFramework.WebServer.Mcp;
49+
50+
public class McpPrompts
51+
{
52+
[McpServerPrompt("echo_sanity_check", "Echo test prompt")]
53+
public static PromptMessage[] EchoSanityCheck()
54+
{
55+
return new PromptMessage[]
56+
{
57+
new PromptMessage("Call Echo with the string 'Hello MCP world!' and return the response.")
58+
};
59+
}
60+
61+
[McpServerPrompt("summarize_person", "Summarize a person with age threshold")]
62+
[McpPromptParameter("ageThreshold", "The age threshold to determine if the person is a senior or junior.")]
63+
public static PromptMessage[] SummarizePerson(string ageThreshold)
64+
{
65+
return new PromptMessage[]
66+
{
67+
new PromptMessage($"Call GetDefaultPerson, then if person.Age > {ageThreshold} label as senior, else junior.")
68+
};
69+
}
70+
}
71+
```
72+
73+
Prompts are listed and invoked via the MCP protocol, just like tools.
3874

3975
### Supported Version
4076

@@ -309,6 +345,11 @@ public static void Main()
309345
typeof(SensorTools)
310346
});
311347

348+
// Discover and register prompts
349+
McpPromptRegistry.DiscoverPrompts(new Type[] {
350+
typeof(McpPrompts)
351+
});
352+
312353
// Step 3: Start WebServer with MCP support
313354
using (var server = new WebServer(80, HttpProtocol.Http, new Type[] { typeof(McpServerController) }))
314355
{
@@ -482,7 +523,8 @@ POST /mcp
482523
}
483524
```
484525

485-
### 2. Tool Discovery
526+
527+
### 2. Tool and Prompt Discovery
486528

487529
Agent discovers available tools:
488530

@@ -495,7 +537,18 @@ POST /mcp
495537
}
496538
```
497539

498-
The response will be the list of the tools. See next section for detailed examples.
540+
And prompts:
541+
542+
```json
543+
POST /mcp
544+
{
545+
"jsonrpc": "2.0",
546+
"method": "prompts/list",
547+
"id": 2
548+
}
549+
```
550+
551+
There will be responses for tools and prompts. See next section for detailed examples.
499552

500553
### 3. Tool Invocation
501554

@@ -519,15 +572,15 @@ POST /mcp
519572

520573
## Request/Response Examples
521574

522-
This section shows real exampled of requests and responses.
575+
This section shows real examples of requests and responses.
576+
523577

524578
### Tool Discovery
525579

526580
**Request:**
527581

528582
```json
529583
POST /mcp
530-
531584
{
532585
"jsonrpc": "2.0",
533586
"method": "tools/list",
@@ -611,6 +664,61 @@ POST /mcp
611664
}
612665
```
613666

667+
### Prompt Discovery
668+
669+
**Request:**
670+
671+
```json
672+
POST /mcp
673+
{
674+
"jsonrpc": "2.0",
675+
"method": "prompts/list",
676+
"id": 1
677+
}
678+
```
679+
680+
**Response:**
681+
682+
```json
683+
{
684+
"jsonrpc": "2.0",
685+
"id": 1,
686+
"result": {
687+
"prompts": [
688+
{
689+
"name": "echo_sanity_check",
690+
"description": "Echo test prompt",
691+
"parameters": [],
692+
"messages": [
693+
{
694+
"role": "system",
695+
"content": "Call Echo with the string 'Hello MCP world!' and return the response."
696+
}
697+
]
698+
},
699+
{
700+
"name": "summarize_person",
701+
"description": "Summarize a person with age threshold",
702+
"parameters": [
703+
{
704+
"name": "ageThreshold",
705+
"description": "The age threshold to determine if the person is a senior or junior.",
706+
"type": "string"
707+
}
708+
],
709+
"messages": [
710+
{
711+
"role": "system",
712+
"content": "Call GetDefaultPerson, then if person.Age > {ageThreshold} label as senior, else junior."
713+
}
714+
]
715+
}
716+
],
717+
"nextCursor": null
718+
}
719+
}
720+
```
721+
614722
### Simple Tool Invocation
615723

616724
**Request:**
@@ -714,6 +822,78 @@ POST /mcp
714822
}
715823
```
716824

825+
### Prompt usage
826+
827+
#### Prompt Retrieval Example
828+
829+
To retrieve a prompt, use the `prompts/get` method. Provide the prompt name and any required parameters.
830+
831+
**Request:**
832+
833+
```json
834+
POST /mcp
835+
{
836+
"jsonrpc": "2.0",
837+
"method": "prompts/get",
838+
"params": {
839+
"name": "echo_sanity_check",
840+
"arguments": {}
841+
},
842+
"id": 5
843+
}
844+
```
845+
846+
**Response:**
847+
848+
```json
849+
{
850+
"jsonrpc": "2.0",
851+
"id": 5,
852+
"result": {
853+
"messages": [
854+
{
855+
"role": "system",
856+
"content": "Call Echo with the string 'Hello MCP world!' and return the response."
857+
}
858+
]
859+
}
860+
}
861+
```
862+
863+
If the prompt requires parameters, include them in the `arguments` object:
864+
865+
```json
866+
POST /mcp
867+
{
868+
"jsonrpc": "2.0",
869+
"method": "prompts/get",
870+
"params": {
871+
"name": "summarize_person",
872+
"arguments": {
873+
"ageThreshold": "65"
874+
}
875+
},
876+
"id": 6
877+
}
878+
```
879+
880+
**Response:**
881+
882+
```json
883+
{
884+
"jsonrpc": "2.0",
885+
"id": 6,
886+
"result": {
887+
"messages": [
888+
{
889+
"role": "system",
890+
"content": "Call GetDefaultPerson, then if person.Age > 65 label as senior, else junior."
891+
}
892+
]
893+
}
894+
}
895+
```
896+
717897
## Error Handling
718898

719899
The .NET nanoFramework MCP Server knows how to handle properly errors. The following will show examples of request and error responses.

0 commit comments

Comments
 (0)