2020- [ Core Concepts] ( #core-concepts )
2121 - [ Server] ( #server )
2222 - [ Tools] ( #tools )
23+ - [ Providers] ( #providers )
2324 - [ Resources] ( #resources )
2425 - [ Prompts] ( #prompts )
2526- [ Running Your Server] ( #running-your-server )
26- - [ stdio ] ( #stdio )
27+ - [ STDIO ] ( #stdio )
2728 - [ HTTP with SSE] ( #http-with-sse )
2829 - [ Multi-Protocol] ( #multi-protocol )
2930 - [ Testing and Debugging] ( #testing-and-debugging )
@@ -71,8 +72,9 @@ import (
7172)
7273
7374func main () {
74- // Create a logger
75- logger := log.New (os.Stdout , " [cortex] " , log.LstdFlags )
75+ // Create a logger that writes to stderr instead of stdout
76+ // This is critical for STDIO servers as stdout must only contain JSON-RPC messages
77+ logger := log.New (os.Stderr , " [cortex] " , log.LstdFlags )
7678
7779 // Create the server
7880 mcpServer := server.NewMCPServer (" Echo Server Example" , " 1.0.0" , logger)
@@ -93,10 +95,10 @@ func main() {
9395 logger.Fatalf (" Error adding tool: %v " , err)
9496 }
9597
96- // Start the server
97- fmt.Println ( " Starting Echo Server..." )
98- fmt.Println ( " Send JSON-RPC messages via stdin to interact with the server." )
99- fmt.Println ( ` Try: {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"echo","parameters":{"message":"Hello, World!"}}}` )
98+ // Write server status to stderr instead of stdout to maintain clean JSON protocol
99+ fmt.Fprintf (os. Stderr , " Starting Echo Server...\n " )
100+ fmt.Fprintf (os. Stderr , " Send JSON-RPC messages via stdin to interact with the server.\n " )
101+ fmt.Fprintf (os. Stderr , ` Try: {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"echo","parameters":{"message":"Hello, World!"}}}\n ` )
100102
101103 // Serve over stdio
102104 if err := mcpServer.ServeStdio (); err != nil {
@@ -141,8 +143,8 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is a standar
141143The MCP Server is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing:
142144
143145``` go
144- // Create a new MCP server
145- mcpServer := server.NewMCPServer (" My App" , " 1.0.0" )
146+ // Create a new MCP server with logger
147+ mcpServer := server.NewMCPServer (" My App" , " 1.0.0" , logger )
146148```
147149
148150### Tools
@@ -171,6 +173,24 @@ calculatorTool := tools.NewTool("calculator",
171173mcpServer.AddTool (ctx, calculatorTool, handleCalculator)
172174```
173175
176+ ### Providers
177+
178+ Providers allow you to group related tools and resources into a single package that can be easily registered with a server:
179+
180+ ``` go
181+ // Create a weather provider
182+ weatherProvider , err := weather.NewWeatherProvider (logger)
183+ if err != nil {
184+ logger.Fatalf (" Failed to create weather provider: %v " , err)
185+ }
186+
187+ // Register the provider with the server
188+ err = mcpServer.RegisterProvider (ctx, weatherProvider)
189+ if err != nil {
190+ logger.Fatalf (" Failed to register weather provider: %v " , err)
191+ }
192+ ```
193+
174194### Resources
175195
176196Resources are how you expose data to LLMs. They're similar to GET endpoints in a REST API - they provide data but shouldn't perform significant computation or have side effects:
@@ -212,7 +232,7 @@ codeReviewPrompt := &domain.Prompt{
212232
213233MCP servers in Go can be connected to different transports depending on your use case:
214234
215- ### stdio
235+ ### STDIO
216236
217237For command-line tools and direct integrations:
218238
@@ -224,6 +244,16 @@ if err := mcpServer.ServeStdio(); err != nil {
224244}
225245```
226246
247+ IMPORTANT: When using STDIO, all logs must be directed to stderr to maintain the clean JSON-RPC protocol on stdout:
248+
249+ ``` go
250+ // Create a logger that writes to stderr
251+ logger := log.New (os.Stderr , " [cortex] " , log.LstdFlags )
252+
253+ // All debug/status messages should use stderr
254+ fmt.Fprintf (os.Stderr , " Server starting...\n " )
255+ ```
256+
227257### HTTP with SSE
228258
229259For web applications, you can use Server-Sent Events (SSE) for real-time communication:
@@ -247,108 +277,113 @@ if err := mcpServer.Shutdown(ctx); err != nil {
247277
248278### Multi-Protocol
249279
250- You can also run multiple protocol servers simultaneously:
280+ You can also run multiple protocol servers simultaneously by using goroutines :
251281
252282``` go
253- // Configure server for both HTTP and stdio
254- mcpServer := server.NewMCPServer (" Multi-Protocol Server" , " 1.0.0" )
255- mcpServer.SetAddress (" :8080" )
256- mcpServer.AddTool (ctx, echoTool, handleEcho)
257-
258- // Start HTTP server in a goroutine
283+ // Start an HTTP server
259284go func () {
260285 if err := mcpServer.ServeHTTP (); err != nil {
261286 log.Fatalf (" HTTP server error: %v " , err)
262287 }
263288}()
264289
265- // Start stdio server in the main thread
266- if err := mcpServer.ServeStdio (); err != nil {
267- log.Fatalf (" Stdio server error: %v " , err)
268- }
290+ // Start a STDIO server
291+ go func () {
292+ if err := mcpServer.ServeStdio (); err != nil {
293+ log.Fatalf (" STDIO server error: %v " , err)
294+ }
295+ }()
296+
297+ // Wait for shutdown signal
298+ stop := make (chan os.Signal , 1 )
299+ signal.Notify (stop, os.Interrupt , syscall.SIGTERM )
300+ <- stop
269301```
270302
271303### Testing and Debugging
272304
273- For testing your MCP server, you can use the [ MCP Inspector ] ( https://github.com/modelcontextprotocol/inspector ) or send JSON-RPC messages directly :
305+ For testing and debugging, the Cortex framework provides several utilities :
274306
275- ``` bash
276- # Test an echo tool with stdio
277- echo ' {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"echo","parameters":{"message":"Hello, World!"}}}' | go run your_server.go
307+ ``` go
308+ // You can use the test-call.sh script to send test requests to your STDIO server
309+ // For example:
310+ // ./test-call.sh echo '{"message":"Hello, World!"}'
278311```
279312
280313## Examples
281314
282- Cortex includes several examples in the ` examples ` directory:
283-
284315### Basic Examples
285316
286- - ** stdio-server** : A simple stdio-based MCP server example
287- - ** sse-server** : An HTTP/SSE-based MCP server example
288-
289- ### Advanced Examples
317+ The repository includes several basic examples in the ` examples ` directory:
290318
291- - ** multi-protocol ** : A server that supports both stdio and HTTP protocols
292- - ** providers/weather ** : Weather forecast tool provider
293- - ** providers/database ** : Simple key-value store tool provider
319+ - ** STDIO Server ** : A simple MCP server that communicates via STDIO ( ` examples/stdio-server ` )
320+ - ** SSE Server ** : A server that uses HTTP with Server-Sent Events for communication ( ` examples/sse-server ` )
321+ - ** Multi-Protocol ** : A server that can run on multiple protocols simultaneously ( ` examples/multi-protocol ` )
294322
295- Run the examples using the provided scripts:
323+ ### Advanced Examples
296324
297- ``` bash
298- # Run stdio server
299- ./run-stdio.sh
325+ The examples directory also includes more advanced use cases:
300326
301- # Run SSE server
302- ./run-sse.sh
327+ - ** Providers** : Examples of how to create and use providers to organize related tools (` examples/providers ` )
328+ - ** Weather Provider** : Demonstrates how to create a provider for weather-related tools
329+ - ** Database Provider** : Shows how to create a provider for database operations
303330
304- # Run multi-protocol server (stdio)
305- ./run-flexible-stdio.sh
331+ ### Plugin System
306332
307- # Run multi-protocol server (HTTP)
308- ./run-flexible-http.sh
309- ```
333+ Cortex includes a plugin system for extending server capabilities:
310334
311- You can also run them directly with Go:
335+ ``` go
336+ // Create a new provider based on the BaseProvider
337+ type MyProvider struct {
338+ *plugin.BaseProvider
339+ }
312340
313- ``` bash
314- go run examples/stdio-server/main.go
315- go run examples/sse-server/main.go
316- go run examples/multi-protocol/main.go -protocol stdio
317- go run examples/multi-protocol/main.go -protocol http -address localhost:8080
341+ // Create a new provider instance
342+ func NewMyProvider (logger *log .Logger ) (*MyProvider , error ) {
343+ info := plugin.ProviderInfo {
344+ ID: " my-provider" ,
345+ Name: " My Provider" ,
346+ Version: " 1.0.0" ,
347+ Description: " A custom provider for my tools" ,
348+ Author: " Your Name" ,
349+ URL: " https://github.com/yourusername/myrepo" ,
350+ }
351+
352+ baseProvider := plugin.NewBaseProvider (info, logger)
353+ provider := &MyProvider{
354+ BaseProvider: baseProvider,
355+ }
356+
357+ // Register tools with the provider
358+ // ...
359+
360+ return provider, nil
361+ }
318362```
319363
320- ### Plugin System
321-
322- Cortex includes a flexible plugin system that allows external services to register as tools. See the ` pkg/plugin ` directory for more information.
323-
324364## Package Structure
325365
326- The library is organized following clean architecture principles :
366+ The Cortex codebase is organized into several packages :
327367
328- ```
329- cortex/
330- ├── pkg/ # Public API (exposed to users)
331- │ ├── plugin/ # Plugin system for external tools
332- │ ├── server/ # Public server implementation
333- │ ├── tools/ # Utilities for creating MCP tools
334- │ └── types/ # Shared types and interfaces
335- ├── internal/ # Private implementation details
336- ├── examples/ # Example code snippets and use cases
337- │ ├── stdio-server/ # Stdio server example
338- │ ├── sse-server/ # SSE server example
339- │ ├── multi-protocol/ # Multi-protocol server example
340- │ └── providers/ # Example tool providers
341- ```
342-
343- The ` pkg/ ` directory contains all publicly exposed APIs that users of the library should interact with.
368+ - ` pkg/server ` : Core server implementation
369+ - ` pkg/tools ` : Tool creation and management
370+ - ` pkg/plugin ` : Plugin system for extending server capabilities
371+ - ` pkg/types ` : Common types and interfaces
372+ - ` pkg/builder ` : Builders for creating complex objects
344373
345374## Contributing
346375
347376Contributions are welcome! Please feel free to submit a Pull Request.
348377
378+ 1 . Fork the repository
379+ 2 . Create your feature branch (` git checkout -b feature/amazing-feature ` )
380+ 3 . Commit your changes (` git commit -m 'Add some amazing feature' ` )
381+ 4 . Push to the branch (` git push origin feature/amazing-feature ` )
382+ 5 . Open a Pull Request
383+
349384## License
350385
351- This project is licensed under the MIT License - see the [ LICENSE] ( LICENSE ) file for details.
386+ This project is licensed under the MIT License - see the LICENSE file for details.
352387
353388## Support & Contact
354389
0 commit comments