Some checks failed
Test / rust-fmt-check (pull_request) Failing after 0s
Test / rust-clippy (pull_request) Failing after 1s
Test / rust-tests (pull_request) Failing after 0s
Test / frontend-typecheck (pull_request) Failing after 16s
Test / frontend-tests (pull_request) Failing after 18s
PR Review Automation / review (pull_request) Failing after 4m13s
Complete backport of all features from apollo_nxt-trcaa repository: - Three-tier shell execution safety system (Tier 1: auto, Tier 2: approve, Tier 3: deny) - Ollama function calling with tool use support - AI provider tool calling auto-detection - kubectl binary bundling and management - kubeconfig upload and context management - Shell approval modal with real-time UI - MCP protocol HTTP transport with custom headers - Enhanced security audit logging - Comprehensive test coverage (275+ tests) - Updated CI/CD workflows for Gitea Actions - Complete documentation (ADRs, wiki, release notes) Sanitization applied to all files: - Removed all MSI, Motorola, VNXT, Vesta references - Replaced internal infrastructure references with TFTSR equivalents - Updated all URLs and API endpoints - Sanitized commit history references in documentation Technical changes: - New modules: shell/classifier, shell/executor, shell/kubectl, shell/kubeconfig - Enhanced AI providers: ollama.rs, openai.rs with function calling - New Tauri commands: shell execution, kubeconfig management, tool calling detection - Database migrations: shell_execution_audit table - Frontend: ShellApprovalModal, ShellExecution, KubeconfigManager pages - CI/CD: kubectl bundling, multi-platform builds, Gitea Actions integration Version: 1.0.8 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
215 lines
7.1 KiB
Markdown
215 lines
7.1 KiB
Markdown
# ADR-008: Model Context Protocol for External Tools
|
|
|
|
**Date**: 2026-06-02
|
|
**Status**: Accepted
|
|
**Deciders**: Shaun Arman, Henry Castle
|
|
**Context**: Hackathon v1.0.0 — Extensible Tool Integration
|
|
|
|
---
|
|
|
|
## Context
|
|
|
|
TRCAA v1.0.0 introduced agentic shell execution with statically-defined tools (`execute_shell_command`, `add_ado_comment`). As the application grows, we need a way to integrate external tools and services without hardcoding every integration into the Rust backend.
|
|
|
|
**Requirements**:
|
|
- AI agents need access to third-party tools (GitHub, Slack, monitoring systems, etc.)
|
|
- Tool definitions should be discoverable and documented
|
|
- Tool execution should be sandboxed and timeout-protected
|
|
- New tools should be addable without recompiling the application
|
|
- Support both local processes (stdio) and remote services (HTTP)
|
|
|
|
**Alternatives Considered**:
|
|
|
|
1. **Plugin system (dynamic library loading)**
|
|
- ✅ Native Rust plugins with full system access
|
|
- ❌ Security risk — malicious plugins have full process access
|
|
- ❌ Unsafe Rust (`dlopen`, FFI) for plugin loading
|
|
- ❌ Platform-specific (.so, .dylib, .dll)
|
|
- ❌ No sandboxing
|
|
|
|
2. **WebAssembly plugins (wasmtime)**
|
|
- ✅ Sandboxed execution with WASI
|
|
- ✅ Cross-platform (single .wasm file)
|
|
- ❌ Complex WASI interface design
|
|
- ❌ WASI preview2 still unstable
|
|
- ❌ Limited async support
|
|
|
|
3. **gRPC tool server protocol**
|
|
- ✅ Industry-standard RPC
|
|
- ✅ Strongly typed with protobuf
|
|
- ❌ Complex setup for simple tools
|
|
- ❌ Every tool server needs gRPC boilerplate
|
|
- ❌ No existing ecosystem
|
|
|
|
4. **Model Context Protocol (MCP)**
|
|
- ✅ Designed specifically for AI tool integration
|
|
- ✅ Existing ecosystem (Anthropic, community servers)
|
|
- ✅ Supports stdio (local processes) and HTTP (remote services)
|
|
- ✅ JSON-RPC 2.0 protocol (simple, well-understood)
|
|
- ✅ Tool discovery built into protocol
|
|
- ❌ New protocol (May 2024), potential churn
|
|
|
|
---
|
|
|
|
## Decision
|
|
|
|
**Adopt the Model Context Protocol (MCP) for external tool integration, using the `rmcp` Rust client library.**
|
|
|
|
### Architecture
|
|
|
|
```
|
|
AI Agent → MCP Adapter → MCP Client → Transport (stdio/HTTP) → MCP Server
|
|
↓
|
|
External Tool
|
|
```
|
|
|
|
**Components**:
|
|
|
|
| Module | Responsibility |
|
|
|--------|---------------|
|
|
| `mcp/client.rs` | Connect to MCP servers (stdio/HTTP) |
|
|
| `mcp/adapter.rs` | Merge MCP tools with static tools |
|
|
| `mcp/discovery.rs` | Health check servers, update status |
|
|
| `mcp/store.rs` | Persist server configs and tools to database |
|
|
| `mcp/models.rs` | McpServer, McpTool, McpResource types |
|
|
| `mcp/transport/stdio.rs` | Spawn processes with env vars |
|
|
| `mcp/transport/http.rs` | HTTP POST with auth headers |
|
|
|
|
**Database Schema** (Migration 018):
|
|
|
|
```sql
|
|
CREATE TABLE mcp_servers (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
url TEXT NOT NULL,
|
|
transport_type TEXT NOT NULL CHECK(transport_type IN ('stdio', 'http')),
|
|
auth_type TEXT NOT NULL CHECK(auth_type IN ('none', 'api_key', 'bearer', 'oauth2')),
|
|
auth_value TEXT,
|
|
enabled INTEGER NOT NULL DEFAULT 1,
|
|
discovery_status TEXT NOT NULL DEFAULT 'pending'
|
|
CHECK(discovery_status IN ('pending','connected','unreachable','error')),
|
|
env_config TEXT, -- JSON map of environment variables
|
|
...
|
|
);
|
|
|
|
CREATE TABLE mcp_tools (
|
|
id TEXT PRIMARY KEY,
|
|
server_id TEXT NOT NULL,
|
|
name TEXT NOT NULL,
|
|
tool_key TEXT NOT NULL, -- "server_name.tool_name"
|
|
description TEXT,
|
|
parameters TEXT NOT NULL, -- JSON schema
|
|
FOREIGN KEY(server_id) REFERENCES mcp_servers(id) ON DELETE CASCADE
|
|
);
|
|
```
|
|
|
|
**Tool Calling Flow**:
|
|
|
|
1. User configures MCP server in Settings (name, URL/command, transport type, auth)
|
|
2. TRCAA connects and calls `list_tools()` to discover available tools
|
|
3. Tools stored in `mcp_tools` table with namespaced key (`server_name.tool_name`)
|
|
4. AI agent requests tools via `get_enabled_mcp_tools()`
|
|
5. MCP tools merged with static tools (`execute_shell_command`, `add_ado_comment`)
|
|
6. AI agent calls tool by key (e.g., `github.create_issue`)
|
|
7. Adapter routes to correct MCP client
|
|
8. Client invokes tool with **30-second hard timeout**
|
|
9. Result returned to AI agent
|
|
|
|
**Safety Features**:
|
|
|
|
- **Timeout protection**: 30-second hard timeout prevents indefinite hangs from misbehaving servers
|
|
- **Process isolation**: Stdio servers run as separate processes with isolated env vars
|
|
- **Auth encryption**: API keys encrypted with AES-256-GCM before storage
|
|
- **User control**: Users explicitly enable/disable each MCP server
|
|
- **Status tracking**: Connection health displayed in UI (connected, unreachable, error)
|
|
|
|
---
|
|
|
|
## Consequences
|
|
|
|
### Positive
|
|
|
|
- **Extensibility**: New tools without recompiling (add MCP server in Settings)
|
|
- **Ecosystem**: Can use community MCP servers (GitHub, Slack, Prometheus, etc.)
|
|
- **Simplicity**: JSON-RPC 2.0 protocol is simple to implement and debug
|
|
- **Dual transport**: Supports both local tools (stdio) and cloud services (HTTP)
|
|
- **Discovery**: Tool schemas fetched automatically via `list_tools()`
|
|
- **Sandboxing**: Stdio processes isolated, HTTP calls timeout-protected
|
|
|
|
### Negative
|
|
|
|
- **Protocol churn risk**: MCP is new (May 2024), spec may evolve
|
|
- **Dependency**: Relies on `rmcp` crate maintenance
|
|
- **Stdio complexity**: Process spawning platform-dependent (Windows cmd.exe vs Unix bash)
|
|
- **Debugging**: Tool call failures require inspecting both TRCAA logs and MCP server logs
|
|
|
|
### Trade-offs
|
|
|
|
We chose **extensibility and ecosystem over protocol maturity**. MCP's design aligns with our use case (AI tool calling), and the 30-second timeout mitigates the risk of server misbehavior.
|
|
|
|
---
|
|
|
|
## Implementation Notes
|
|
|
|
**Example: Stdio MCP Server**
|
|
|
|
```bash
|
|
# User configures in Settings UI:
|
|
Name: GitHub Tools
|
|
Transport: stdio
|
|
Command: npx
|
|
Args: @modelcontextprotocol/server-github
|
|
Env: GITHUB_TOKEN=ghp_...
|
|
```
|
|
|
|
TRCAA spawns process, sends JSON-RPC 2.0 requests over stdin/stdout:
|
|
|
|
```json
|
|
{"jsonrpc":"2.0","method":"tools/list","id":1}
|
|
```
|
|
|
|
Server responds:
|
|
|
|
```json
|
|
{
|
|
"jsonrpc":"2.0",
|
|
"id":1,
|
|
"result":{
|
|
"tools":[
|
|
{"name":"create_issue","description":"Create a GitHub issue","inputSchema":{...}},
|
|
{"name":"list_commits","description":"List commits","inputSchema":{...}}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
**Example: HTTP MCP Server**
|
|
|
|
```bash
|
|
# User configures:
|
|
Name: Internal Monitoring
|
|
Transport: http
|
|
URL: https://monitoring.internal.com/mcp
|
|
Auth Type: bearer
|
|
Auth Value: eyJ...
|
|
```
|
|
|
|
TRCAA sends HTTP POST to `/mcp` with `Authorization: Bearer eyJ...` header.
|
|
|
|
---
|
|
|
|
## Related Decisions
|
|
|
|
- **ADR-007**: Three-Tier Shell Safety (MCP tools bypass shell classification — server responsibility)
|
|
- Future: **ADR-010**: MCP Tool Approval System (extend three-tier safety to MCP tools)
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- **MCP Specification**: https://spec.modelcontextprotocol.io/
|
|
- **rmcp Rust Client**: https://github.com/tankeez/rmcp
|
|
- **Implementation PR**: #32 (Hackathon v1.0.0)
|
|
- **Database Schema**: Migration 018 (`mcp_servers`, `mcp_tools`, `mcp_resources`)
|
|
- **Wiki**: `docs/wiki/AI-Providers.md` (Tool Calling section)
|