Skip to content

Commit 522ad84

Browse files
committed
feat: update readme
1 parent 9d81873 commit 522ad84

File tree

1 file changed

+108
-73
lines changed

1 file changed

+108
-73
lines changed

README.md

Lines changed: 108 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
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

7374
func 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
141143
The 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",
171173
mcpServer.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

176196
Resources 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

213233
MCP servers in Go can be connected to different transports depending on your use case:
214234

215-
### stdio
235+
### STDIO
216236

217237
For 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

229259
For 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
259284
go 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

347376
Contributions 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

Comments
 (0)