MCP Integration
Luna connects to Model Context Protocol (MCP) servers to extend the agent's capabilities beyond built-in tools. MCP servers provide additional tools, resources, and prompt templates through a standardized JSON-RPC protocol.
Overview
Luna Agent
|
+-- Built-in tools (bash, read_file, write_file, ...)
|
+-- MCP Manager
+-- MCP Server 1 (stdio) -> filesystem tools
+-- MCP Server 2 (stdio) -> GitHub tools
+-- MCP Server 3 (stdio) -> database toolsMCP tools are discovered automatically on connection and merged with built-in tools. The LLM sees all tools (built-in + MCP) in its tool list, prefixed with mcp__.
Protocol Version
Luna implements the Model Context Protocol specification (2025-03-26), supporting:
initializehandshake with capability negotiationtools/listfor tool discoverytools/callfor tool executionresources/readfor resource accessprompts/getfor prompt template retrieval
Transport
stdio Transport
Communication via stdin/stdout JSON-RPC. Each server runs as a separate subprocess.
Content-Lengthheader support for framing- Multi-server support -- connect to multiple MCP servers simultaneously
- Best-effort connection model
HTTP Transport
Luna also supports HTTP-based MCP servers for remote tool access. HTTP transport enables connections to MCP servers that are not local processes.
Configuration
Global Config: ~/.luna/mcp.json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
}
}
}
}Project-local Config: .luna/mcp.json
Same format as global config. Project-local config is merged with global config. Project-local takes precedence on conflicts.
Config Structure
| Field | Type | Required | Description |
|---|---|---|---|
command | string | Yes | Command to start the MCP server |
args | array | No | Arguments to pass to the command |
env | object | No | Environment variables for the server process |
Tool Discovery
When Luna starts:
- Reads MCP config (global + project-local, merged)
- Starts each configured server as a subprocess
- Sends
initializeandtools/listJSON-RPC requests - Merges discovered tools into the agent's tool registry
- The LLM sees all tools (built-in + MCP) in its system prompt
Discovered MCP tools are prefixed with mcp__ in the tool registry (e.g., mcp__github_create_issue).
Multi-Server Management
Luna can connect to multiple MCP servers simultaneously. Each server runs as an independent subprocess with its own lifecycle:
- Servers are started in parallel during initialization
- Each server's tools are namespaced by server name
- If one server fails, others continue operating normally
- Use
mcp_read_resourceandmcp_get_promptwith the optionalserverparameter to target a specific server
OAuth PKCE
Luna supports OAuth 2.0 with PKCE (Proof Key for Code Exchange) for MCP servers that require authentication:
- Luna generates a code verifier and challenge
- Starts a local callback server via FFI raw socket
- Opens the authorization URL in the user's browser
- Receives the authorization code at the callback URL
- Exchanges the code for an access token using the code verifier
- Stores the token for subsequent API calls
OAuth configuration is specified per-server in the MCP config.
Luna as MCP Server
Luna can also act as an MCP server, exposing its built-in tools to external MCP clients. This enables other applications to use Luna's file operations, code intelligence, and other capabilities through the standard MCP protocol.
When running as an MCP server, Luna:
- Responds to
initializeandtools/listrequests - Executes tools via
tools/calland returns results - Supports the same JSON-RPC message format
Example MCP Servers
Filesystem Access
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
}
}
}GitHub Integration
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
}
}
}
}PostgreSQL Queries
{
"mcpServers": {
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://user:pass@localhost/db"]
}
}
}Custom MCP Server
Any MCP-compatible server can be used. The server must:
- Accept JSON-RPC requests on stdin
- Respond with JSON-RPC responses on stdout
- Support
initializeandtools/listmethods - Follow the MCP specification
Best-Effort Connection
MCP connections are best-effort:
| Scenario | Behavior |
|---|---|
| Server fails to start | Luna logs a warning and continues without its tools |
| Server crashes mid-session | Luna logs the error and continues with remaining tools |
| Server restarts | Manual restart required |
Troubleshooting
MCP server not connecting:
- Check the
commandpath is correct and the binary exists - Check
argsare properly formatted - Check environment variables (especially API keys)
- Look for errors in
~/.luna/logs/
MCP tools not appearing:
- Ensure the server supports
tools/listmethod - Check that the server starts without errors
- Verify the server responds to
initializerequest - Use
/tools-reloadto rescan after fixing configuration