Skip to main content

Overview

LuaMCPServer allows you to connect external MCP (Model Context Protocol) servers to your agent. MCP servers provide additional tools that your agent can use at runtime, enabling integration with APIs, databases, documentation services, and more.
import { LuaMCPServer, env } from 'lua-cli';

const docsServer = new LuaMCPServer({
  name: 'docs',
  transport: 'streamable-http',
  url: 'https://mcp.example.com/mcp',
  headers: () => ({
    'Authorization': `Bearer ${env("MCP_API_KEY")}`
  })
});

export default docsServer;
What is MCP? The Model Context Protocol (MCP) is an open standard for connecting AI models to external tools and data sources. Learn more at modelcontextprotocol.io.

Why MCP Servers?

Extend Capabilities

Add tools without writing code - use existing MCP servers

Standard Protocol

Compatible with any MCP-compliant server

Remote Integration

Connect to hosted MCP services via HTTP

Community Ecosystem

Access growing library of hosted MCP servers

Transport Types

MCP servers support two HTTP-based transport methods:
stdio transport not supported yet: Local MCP servers (using npx, node, etc.) are not supported yet. Please use remote MCP servers with streamable-http or sse transport instead.

Constructor

new LuaMCPServer(config)

Creates a new MCP server configuration.
config
LuaMCPServerConfig
required
MCP server configuration object

Configuration Parameters

Required Fields

name
string
required
Unique identifier for the MCP serverFormat: lowercase, hyphens allowedExamples: 'docs-server', 'api-gateway', 'database'
transport
'streamable-http' | 'sse'
required
Transport protocol for communication
  • 'streamable-http' - Modern MCP standard (recommended)
  • 'sse' - Legacy Server-Sent Events transport
url
string | (() => string)
required
URL of the remote MCP serverCan be a static string or a function that returns the URL at runtime using env().Examples:
  • 'https://mcp.example.com/mcp'
  • () => env("MCP_SERVER_URL")

Optional Fields

headers
Record<string, string> | (() => Record<string, string>)
HTTP headers to send with requestsCan be a static object or a function that returns headers at runtime using env().Example (static): { 'X-Custom-Header': 'value' }Example (dynamic): () => ({ 'Authorization': \Bearer $` })`
timeout
number
Timeout in milliseconds for server operationsDefault: 60000 (60 seconds)

Examples

Documentation Server

import { LuaMCPServer, env } from 'lua-cli';

const docsServer = new LuaMCPServer({
  name: 'docs',
  transport: 'streamable-http',
  url: 'https://docs.example.com/mcp',
  headers: () => ({
    'Authorization': `Bearer ${env("DOCS_API_KEY")}`
  }),
  timeout: 30000
});

export default docsServer;

API Gateway

import { LuaMCPServer, env } from 'lua-cli';

const apiServer = new LuaMCPServer({
  name: 'api-gateway',
  transport: 'streamable-http',
  url: 'https://api.example.com/mcp',
  headers: () => ({
    'Authorization': `Bearer ${env("API_TOKEN")}`,
    'X-Api-Version': '2024-01'
  }),
  timeout: 45000
});

export default apiServer;

Database Service

import { LuaMCPServer, env } from 'lua-cli';

const dbServer = new LuaMCPServer({
  name: 'database',
  transport: 'streamable-http',
  url: 'https://db-mcp.example.com/mcp',
  headers: () => ({
    'Authorization': `Bearer ${env("DB_API_KEY")}`,
    'X-Database': 'production'
  }),
  timeout: 60000
});

export default dbServer;

Dynamic URL with env()

import { LuaMCPServer, env } from 'lua-cli';

const server = new LuaMCPServer({
  name: 'dynamic-server',
  transport: 'streamable-http',
  url: () => env("MCP_SERVER_URL"),
  headers: () => ({
    'Authorization': `Bearer ${env("API_TOKEN")}`
  })
});

export default server;

Legacy SSE Server

import { LuaMCPServer, env } from 'lua-cli';

const legacyServer = new LuaMCPServer({
  name: 'legacy-api',
  transport: 'sse',
  url: 'https://old-mcp.example.com/sse',
  headers: () => ({
    'Authorization': `Bearer ${env("API_KEY")}`
  })
});

export default legacyServer;

Using with LuaAgent

MCP servers are added to your agent configuration:
import { LuaAgent, LuaSkill, env } from 'lua-cli';

const docsServer = new LuaMCPServer({
  name: 'docs',
  transport: 'streamable-http',
  url: 'https://docs.example.com/mcp',
  headers: () => ({
    'Authorization': `Bearer ${env("DOCS_API_KEY")}`
  })
});

const coreSkill = new LuaSkill({
  name: 'core-skill',
  description: 'Core functionality',
  tools: [...]
});

export const agent = new LuaAgent({
  name: 'docs-assistant',
  persona: 'You are an assistant with access to documentation.',
  skills: [coreSkill],
  
  // Add MCP servers
  mcpServers: [docsServer]
});

Lifecycle Management

Compile

During lua compile, MCP servers are:
  1. Detected from your source code
  2. Registered with the server (if new)
  3. Assigned an ID stored in lua.skill.yaml
  4. Configuration written to dist/mcp-servers.json

Push

Push individual MCP server:
lua push mcp
# Select server from list
Or push all components:
lua push all --force

Activate / Deactivate

MCP servers start inactive. Activate to make tools available:
lua mcp activate
# Select server to activate

lua mcp deactivate
# Select server to deactivate

List / Delete

lua mcp list              # Show all MCP servers
lua mcp delete            # Remove an MCP server

YAML Configuration

After compilation, lua.skill.yaml tracks MCP servers:
agent:
  agentId: your-agent-id
  persona: ...

mcpServers:
  - name: docs
    mcpServerId: mcp_abc123
  - name: api-gateway
    mcpServerId: mcp_def456
The YAML only stores name and mcpServerId. The full configuration (url, headers, etc.) lives in your source code.

Best Practices

Always use env() for API keys and tokens
// ✅ Good - resolved at runtime
headers: () => ({
  'Authorization': `Bearer ${env("API_KEY")}`
})

// ❌ Bad - hardcoded secret
headers: {
  'Authorization': 'Bearer sk_live_xxxx'
}
Adjust timeout based on expected operation duration
// Quick operations
timeout: 10000  // 10 seconds

// Database queries
timeout: 30000  // 30 seconds

// Heavy processing
timeout: 120000 // 2 minutes
Prefer streamable-http transport for new MCP server integrations
// ✅ Recommended - modern standard
transport: 'streamable-http'

// Use only for legacy servers
transport: 'sse'
Keep unused servers deactivated to reduce overhead
# Activate only when needed
lua mcp activate docs-server

# Deactivate when done
lua mcp deactivate docs-server

Troubleshooting

Make sure the server is activated:
lua mcp list      # Check status
lua mcp activate  # Activate if needed
Check the URL is accessible and increase timeout:
const server = new LuaMCPServer({
  transport: 'streamable-http',
  url: 'https://...',
  timeout: 120000  // Increase timeout
});
Verify your API key is correct and set in environment:
# Check environment variable is set
lua env production

# Set the variable
lua env production -k API_KEY -v "your-api-key"
Local MCP servers (stdio) are no longer supported. Migrate to remote servers:
// ❌ No longer supported
transport: 'stdio',
command: 'npx',
args: [...]

// ✅ Use remote transport instead
transport: 'streamable-http',
url: 'https://mcp.example.com/mcp',
headers: () => ({ ... })

See Also