gopher-mcp-rust 0.1.2-11

Rust SDK for Gopher Orch - AI Agent orchestration framework
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
# gopher-mcp-rust - Rust SDK

Rust SDK for Gopher Orch - AI Agent orchestration framework with native C++ performance.

## Table of Contents

- [Features]#features
- [When to Use This SDK]#when-to-use-this-sdk
- [Architecture]#architecture
- [Installation]#installation
- [Quick Start]#quick-start
- [Building from Source]#building-from-source
  - [Prerequisites]#prerequisites
  - [Step 1: Clone the Repository]#step-1-clone-the-repository
  - [Step 2: Build Everything]#step-2-build-everything
  - [Step 3: Verify the Build]#step-3-verify-the-build
  - [Step 4: Run Tests]#step-4-run-tests
- [Native Library Details]#native-library-details
  - [Library Location]#library-location
  - [Platform-Specific Library Names]#platform-specific-library-names
  - [Library Search Order]#library-search-order
- [API Documentation]#api-documentation
  - [GopherAgent]#gopheragent
  - [ConfigBuilder]#configbuilder
  - [Error Handling]#error-handling
- [Examples]#examples
  - [Basic Usage with API Key]#basic-usage-with-api-key
  - [Using Local MCP Servers]#using-local-mcp-servers
  - [Running the Example]#running-the-example
- [Development]#development
  - [Project Structure]#project-structure
  - [Build Scripts]#build-scripts
  - [Rebuilding Native Library]#rebuilding-native-library
  - [Updating Submodules]#updating-submodules
- [Troubleshooting]#troubleshooting
- [Contributing]#contributing
- [License]#license
- [Links]#links
- [Acknowledgments]#acknowledgments

---

## Features

- **Native Performance** - Powered by C++ core with Rust bindings via libloading
- **AI Agent Framework** - Build intelligent agents with LLM integration
- **MCP Protocol** - Model Context Protocol client and server support
- **Tool Orchestration** - Manage and execute tools across multiple MCP servers
- **State Management** - Built-in state graph for complex workflows
- **Memory Safety** - Rust's ownership system with zero-cost abstractions
- **OAuth 2.0 Authentication** - JWT validation with JWKS support (feature-gated)

## When to Use This SDK

This SDK is ideal for:

- **Rust applications** that need high-performance AI agent orchestration
- **Systems programming** requiring MCP protocol support with memory safety
- **CLI tools** integrating AI agents with native performance
- **WebAssembly targets** (with appropriate native library builds)
- **Embedded systems** needing lightweight agent infrastructure

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                    Your Application                         │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│                  Rust SDK (gopher_mcp_rust)                 │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ GopherAgent │  │ConfigBuilder│  │ Error Types         │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                              │ FFI (libloading)
┌─────────────────────────────────────────────────────────────┐
│              Native Library (libgopher-orch)                │
│  ┌───────────────┐  ┌───────────────┐  ┌─────────────────┐  │
│  │ Agent Engine  │  │ LLM Providers │  │ MCP Client      │  │
│  │               │  │ - Anthropic   │  │ - HTTP/SSE      │  │
│  │               │  │ - OpenAI      │  │ - Tool Registry │  │
│  └───────────────┘  └───────────────┘  └─────────────────┘  │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│                    MCP Servers                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ Weather API │  │ Database    │  │ Custom Tools        │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
```

## Installation

### Option 1: From crates.io

```toml
[dependencies]
gopher-mcp-rust = "0.1.2"
```

### Option 2: Git Dependency

```toml
[dependencies]
gopher-mcp-rust = { git = "https://github.com/GopherSecurity/gopher-mcp-rust.git" }
```

### Option 3: Build from Source

See [Building from Source](#building-from-source) section below.

### With Auth Feature

Enable OAuth 2.0 / JWT authentication support:

```toml
[dependencies]
gopher-mcp-rust = { version = "0.1.2", features = ["auth"] }

# Or with git
gopher-mcp-rust = { git = "https://github.com/GopherSecurity/gopher-mcp-rust.git", features = ["auth"] }
```

## Quick Start

```rust
use gopher_mcp_rust::{GopherAgent, ConfigBuilder};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create an agent with API key (fetches server config from remote API)
    let config = ConfigBuilder::new()
        .with_provider("AnthropicProvider")
        .with_model("claude-3-haiku-20240307")
        .with_api_key("your-api-key")
        .build();

    let agent = GopherAgent::create(config)?;

    // Run the agent
    let result = agent.run("What is the weather in Tokyo?")?;
    println!("{}", result);

    // Agent is automatically cleaned up when dropped
    Ok(())
}
```

---

## Building from Source

This SDK wraps a native C++ library via libloading. You must build the native library before using the SDK.

### Prerequisites

| Requirement | Version | Notes |
|-------------|---------|-------|
| Rust | >= 1.64 | Stable toolchain |
| Cargo | Latest | Comes with Rust |
| Git | Latest | For cloning and submodules |
| CMake | >= 3.15 | Native library build system |
| C++ Compiler | C++14+ | Clang (macOS), GCC (Linux), MSVC (Windows) |

**Platform-specific requirements:**

- **macOS**: Xcode Command Line Tools (`xcode-select --install`)
- **Linux**: `build-essential`, `libssl-dev`
- **Windows**: Visual Studio 2019+ with C++ workload

### Step 1: Clone the Repository

```bash
git clone https://github.com/GopherSecurity/gopher-mcp-rust.git
cd gopher-mcp-rust
```

### Step 2: Build Everything

**Using build.sh (recommended)**

The `build.sh` script handles everything automatically:

```bash
./build.sh
```

**Using build.sh with Multiple GitHub Accounts:**

If you have multiple GitHub accounts configured with SSH host aliases, use the `GITHUB_SSH_HOST` environment variable:

```bash
# Use custom SSH host alias for cloning private submodules
GITHUB_SSH_HOST=your-ssh-alias ./build.sh

# Example: if your ~/.ssh/config has "Host github-work" for work account
GITHUB_SSH_HOST=github-work ./build.sh
```

**What happens during build:**

1. **Submodule update** - Initializes and updates submodules (with SSH URL rewriting if `GITHUB_SSH_HOST` is set)
2. **CMake configure** - Configures the C++ build with Release settings
3. **Native compilation** - Compiles C++ to shared libraries
4. **Library installation** - Copies libraries to `native/lib/`
5. **Dependency copying** - Copies required dependencies (gopher-mcp, fmt)
6. **macOS fixes** - Fixes dylib install names for proper runtime loading
7. **Cargo build** - Compiles Rust SDK
8. **Tests** - Runs Cargo tests

### Step 3: Verify the Build

```bash
# Check native libraries were built
ls -la native/lib/

# Expected output (macOS):
# libgopher-orch.dylib
# libgopher-mcp.dylib
# libgopher-mcp-event.dylib
# libfmt.dylib

# Verify Rust build
cargo build
```

### Step 4: Run Tests

```bash
cargo test
```

---

## Native Library Details

### Library Location

After building, native libraries are installed to:

```
native/
├── lib/                          # Shared libraries
│   ├── libgopher-orch.dylib     # Main orchestration library (macOS)
│   ├── libgopher-orch.so        # Main orchestration library (Linux)
│   ├── libgopher-mcp.dylib      # MCP protocol library
│   ├── libgopher-mcp-event.dylib # Event handling
│   └── libfmt.dylib             # Formatting library
└── include/                      # C++ headers (for development)
    └── orch/
        └── core/
```

### Platform-Specific Library Names

| Platform | Library Extension | Example |
|----------|------------------|---------|
| macOS | `.dylib` | `libgopher-orch.dylib` |
| Linux | `.so` | `libgopher-orch.so` |
| Windows | `.dll` | `gopher-orch.dll` |

### Library Search Order

The SDK searches for the native library in this order:

1. `native/lib/` relative to executable
2. `./native/lib/` relative to working directory
3. `CARGO_MANIFEST_DIR/native/lib/` (compile time)
4. System library paths

---

## API Documentation

### GopherAgent

The main struct for creating and running AI agents:

```rust
use gopher_mcp_rust::{GopherAgent, ConfigBuilder, AgentResult};

// Initialize the library (called automatically on first create)
gopher_mcp_rust::init()?;

// Create with API key (fetches server config from remote API)
let config = ConfigBuilder::new()
    .with_provider("AnthropicProvider")
    .with_model("claude-3-haiku-20240307")
    .with_api_key("your-api-key")
    .build();

let agent = GopherAgent::create(config)?;

// Or create with JSON server config
let server_config = r#"
    {
        "succeeded": true,
        "data": {
            "servers": [{
                "serverId": "server1",
                "name": "My MCP Server",
                "transport": "http_sse",
                "config": {"url": "http://localhost:3001/mcp"}
            }]
        }
    }
"#;

let agent = GopherAgent::create_with_server_config(
    "AnthropicProvider",
    "claude-3-haiku-20240307",
    server_config,
)?;

// Run a query
let result = agent.run("Your prompt here")?;

// Run with custom timeout (default: 60000ms)
let result = agent.run_with_timeout("Your prompt here", 30000)?;

// Run with detailed result information
let detailed: AgentResult = agent.run_detailed("Your prompt here");
// Returns AgentResult with: response(), status(), iteration_count(), tokens_used()

// Manual cleanup (optional - happens automatically on drop)
drop(agent);

// Shutdown library
gopher_mcp_rust::shutdown();
```

### ConfigBuilder

Builder for creating agent configurations:

```rust
use gopher_mcp_rust::ConfigBuilder;

// With API key
let config = ConfigBuilder::new()
    .with_provider("AnthropicProvider")
    .with_model("claude-3-haiku-20240307")
    .with_api_key("your-api-key")
    .build();

// With server config
let config = ConfigBuilder::new()
    .with_provider("AnthropicProvider")
    .with_model("claude-3-haiku-20240307")
    .with_server_config(r#"{"succeeded": true, "data": {"servers": []}}"#)
    .build();

// Check configuration
assert!(config.has_api_key());
assert!(!config.has_server_config());
```

### Error Handling

The SDK provides typed errors for different failure scenarios:

```rust
use gopher_mcp_rust::{GopherAgent, ConfigBuilder, Error};

fn main() {
    let config = ConfigBuilder::new()
        .with_provider("AnthropicProvider")
        .with_model("claude-3-haiku-20240307")
        .with_api_key("invalid-key")
        .build();

    match GopherAgent::create(config) {
        Ok(agent) => {
            match agent.run("query") {
                Ok(result) => println!("{}", result),
                Err(Error::Timeout(msg)) => eprintln!("Query timed out: {}", msg),
                Err(e) => eprintln!("Query error: {}", e),
            }
        }
        Err(Error::Library(msg)) => eprintln!("Library not found: {}", msg),
        Err(Error::Config(msg)) => eprintln!("Invalid config: {}", msg),
        Err(Error::Agent(msg)) => eprintln!("Agent error: {}", msg),
        Err(e) => eprintln!("Error: {}", e),
    }
}
```

---

## Examples

### Basic Usage with API Key

```rust
use gopher_mcp_rust::{GopherAgent, ConfigBuilder};
use std::env;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api_key = env::var("GOPHER_API_KEY")?;

    let config = ConfigBuilder::new()
        .with_provider("AnthropicProvider")
        .with_model("claude-3-haiku-20240307")
        .with_api_key(&api_key)
        .build();

    let agent = GopherAgent::create(config)?;

    let answer = agent.run("What time is it in London?")?;
    println!("Answer: {}", answer);

    Ok(())
}
```

### Using Local MCP Servers

```rust
use gopher_mcp_rust::{GopherAgent, ConfigBuilder};

const SERVER_CONFIG: &str = r#"{
    "succeeded": true,
    "code": 200,
    "message": "OK",
    "data": {
        "servers": [
            {
                "version": "1.0.0",
                "serverId": "weather-server",
                "name": "Weather Service",
                "transport": "http_sse",
                "config": {
                    "url": "http://localhost:3001/mcp",
                    "headers": {}
                },
                "connectTimeout": 5000,
                "requestTimeout": 30000
            }
        ]
    }
}"#;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = ConfigBuilder::new()
        .with_provider("AnthropicProvider")
        .with_model("claude-3-haiku-20240307")
        .with_server_config(SERVER_CONFIG)
        .build();

    let agent = GopherAgent::create(config)?;

    let result = agent.run("What is the weather in New York?")?;
    println!("{}", result);

    Ok(())
}
```

### Running the Example

```bash
# Run with the convenience script (starts servers automatically)
cd examples
./client_example_json_run.sh

# Or manually:
# Terminal 1: Start server3001
cd examples/server3001 && npm install && npm run dev

# Terminal 2: Start server3002
cd examples/server3002 && npm install && npm run dev

# Terminal 3: Run the Rust client
ANTHROPIC_API_KEY=your-key cargo run --example client_example_json
```

### Auth MCP Server Example

The `examples/auth` directory contains a complete OAuth 2.0 protected MCP server example using Axum:

```bash
cd examples/auth

# Run with auth disabled (development mode)
./run_example.sh --no-auth

# Run with full OAuth support
./run_example.sh
```

**Features:**
- OAuth 2.0 / OIDC discovery endpoints (RFC 8414, RFC 9728)
- JWT token validation via native library
- Scope-based authorization for MCP tools
- Example weather tools with different scope requirements

**Available Tools:**

| Tool | Scope Required | Description |
|------|----------------|-------------|
| `get-weather` | None | Get current weather for a city |
| `get-forecast` | `mcp:read` | Get 5-day weather forecast |
| `get-weather-alerts` | `mcp:admin` | Get weather alerts for a region |

**Using the Auth Client:**

```rust
use gopher_mcp_rust::GopherAuthClient;

// Create auth client with JWKS endpoint
let client = GopherAuthClient::new(
    "https://auth.example.com/.well-known/jwks.json",
    "https://auth.example.com"
)?;

// Validate a JWT token
let result = client.validate_token("eyJ...", 60);
if result.valid {
    println!("Token is valid!");
    println!("Subject: {}", result.payload.sub);
    println!("Scopes: {:?}", result.payload.scope);
}

// Extract payload without validation
let payload = client.extract_payload("eyJ...")?;
```

See [examples/auth/README.md](examples/auth/README.md) for full documentation.

---

## Development

### Project Structure

```
gopher-mcp-rust/
├── src/
│   ├── lib.rs                    # Library entry point
│   ├── agent.rs                  # GopherAgent implementation
│   ├── config.rs                 # Configuration builder
│   ├── error.rs                  # Error types
│   ├── result.rs                 # AgentResult types
│   └── ffi.rs                    # FFI bindings (libloading)
├── tests/
│   └── ffi_tests.rs              # Integration tests
├── native/                       # Native libraries (generated)
│   ├── lib/                      # Shared libraries (.dylib, .so, .dll)
│   └── include/                  # C++ headers
├── third_party/                  # Git submodules
│   └── gopher-orch/              # C++ implementation
├── examples/                     # Example code
│   ├── client_example_json.rs
│   ├── client_example_json_run.sh
│   ├── server3001/               # Mock weather MCP server
│   └── server3002/               # Mock tools MCP server
├── build.sh                      # Build orchestration script
├── Cargo.toml                    # Cargo build configuration
└── README.md
```

### Build Scripts

| Script | Description |
|--------|-------------|
| `./build.sh` | Full build (submodules + native + Rust SDK) |
| `GITHUB_SSH_HOST=alias ./build.sh` | Build with custom SSH host |
| `cargo build` | Compile Rust SDK |
| `cargo test` | Run tests |
| `cargo build --release` | Release build |
| `cargo run --example client_example_json` | Run example |

### Rebuilding Native Library

If you modify the C++ code or switch branches:

```bash
# Clean and rebuild
rm -rf third_party/gopher-orch/build native/lib
./build.sh
```

### Updating Submodules

To pull latest changes from native libraries:

```bash
# Update to latest commit
cd third_party/gopher-orch
git fetch origin
git checkout <commit-or-branch>
cd ../..

# Rebuild
rm -rf native/lib
./build.sh
```

---

## Troubleshooting

### "Library not found" Error

**Cause**: Native library not built or not in expected location.

**Solution**:
```bash
# Rebuild native library
./build.sh

# Verify library exists
ls native/lib/libgopher-orch.*
```

### "Submodule is empty" Error

**Cause**: Git submodules not initialized.

**Solution**:
```bash
git submodule update --init --recursive
```

### CMake Configuration Fails

**Cause**: Missing dependencies or wrong CMake version.

**Solution**:
```bash
# macOS
brew install cmake

# Linux (Ubuntu/Debian)
sudo apt-get install cmake build-essential libssl-dev

# Verify version
cmake --version  # Should be >= 3.15
```

### Linking Error at Runtime

**Cause**: libloading can't find the native library.

**Solution**:
```bash
# Run from project root
cargo run --example client_example_json

# Or set library path
export DYLD_LIBRARY_PATH=$PWD/native/lib:$DYLD_LIBRARY_PATH  # macOS
export LD_LIBRARY_PATH=$PWD/native/lib:$LD_LIBRARY_PATH      # Linux
```

### Build Fails on Apple Silicon (M1/M2)

**Cause**: Architecture mismatch.

**Solution**:
```bash
# Ensure using native arm64 toolchain
arch -arm64 ./build.sh
```

### Rust Version Compatibility

**Cause**: Using older Rust toolchain.

**Solution**:
```bash
# Update Rust
rustup update stable

# Or use minimum supported version
rustup install 1.64
rustup default 1.64
```

---

## Contributing

Contributions are welcome! Please read our contributing guidelines.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Ensure submodules are initialized (`git submodule update --init --recursive`)
4. Make your changes
5. Run tests (`cargo test`)
6. Commit your changes (`git commit -m 'Add amazing feature'`)
7. Push to the branch (`git push origin feature/amazing-feature`)
8. Open a Pull Request

---

## License

Apache License 2.0 - see [LICENSE](LICENSE) file for details.

## Links

- [GitHub Repository]https://github.com/GopherSecurity/gopher-mcp-rust
- [Java SDK]https://github.com/GopherSecurity/gopher-mcp-java
- [Python SDK]https://github.com/GopherSecurity/gopher-mcp-python
- [TypeScript SDK]https://github.com/GopherSecurity/gopher-orch-js
- [Native C++ Implementation]https://github.com/GopherSecurity/gopher-orch
- [Model Context Protocol]https://modelcontextprotocol.io/

## Acknowledgments

- Built on [gopher-orch]https://github.com/GopherSecurity/gopher-orch C++ framework
- Uses [gopher-mcp]https://github.com/GopherSecurity/gopher-mcp for MCP protocol
- Inspired by LangChain and LangGraph
- FFI bindings via [libloading]https://github.com/nagisa/rust_libloading