MCP Servers

Overview

Armament integrates with MCP (Model Context Protocol) servers to extend agent capabilities with external tools. Agents can access GitHub repos, query databases, search Slack, interact with APIs — anything exposed through an MCP server.

Transports

MCP servers communicate over one of three transports:

TransportUse CaseDescription
stdioLocal toolsSpawns a subprocess, communicates over stdin/stdout
sseLegacy remoteServer-Sent Events (deprecated, use streamable-http)
streamable-httpRemote APIsHTTP with streaming responses (recommended for remote)

Configuration

MCP servers are configured in ~/.armament/config.yaml under the mcp: key.

Stdio Transport

For local tools that run as subprocesses:

mcp:
  filesystem:
    transport: stdio
    command: npx
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]

  github:
    transport: stdio
    command: npx
    args: ["-y", "@modelcontextprotocol/server-github"]
    env:
      GITHUB_TOKEN: ${GITHUB_TOKEN}

Streamable HTTP Transport

For remote APIs (recommended):

mcp:
  custom-api:
    transport: streamable-http
    url: https://mcp.example.com/v1
    auth:
      type: bearer
      token: ${API_TOKEN}

  internal-tools:
    transport: streamable-http
    url: https://tools.internal.company.com/mcp
    auth:
      type: oauth2-code
      clientId: abc123
      authUrl: https://auth.company.com/authorize
      tokenUrl: https://auth.company.com/token
      scopes: ["read", "write"]

SSE Transport (Legacy)

mcp:
  legacy-server:
    transport: sse
    url: https://old-mcp.example.com/events
    auth:
      type: api-key
      header: X-API-Key
      key: ${MCP_API_KEY}

Authentication

HTTP-based transports support multiple auth types:

TypeDescription
noneNo authentication
api-keyStatic API key sent in a header
bearerBearer token in Authorization header
oauth2-codeOAuth2 authorization code with PKCE (opens browser)
oauth2-clientOAuth2 client credentials (machine-to-machine)
oauth2-deviceOAuth2 device code (headless environments)

API Key

auth:
  type: api-key
  header: X-API-Key
  key: ${MY_API_KEY}

Bearer Token

auth:
  type: bearer
  token: ${ACCESS_TOKEN}

OAuth2 Authorization Code

Opens a browser for user consent. Tokens are cached and refreshed automatically.

auth:
  type: oauth2-code
  clientId: my-app-id
  authUrl: https://auth.provider.com/authorize
  tokenUrl: https://auth.provider.com/token
  scopes: ["read", "write", "admin"]
  redirectPort: 8400

OAuth2 Client Credentials

Fully automatic — no user interaction required.

auth:
  type: oauth2-client
  clientId: service-account-id
  clientSecret: ${CLIENT_SECRET}
  tokenUrl: https://auth.provider.com/token
  scopes: ["api.access"]

OAuth2 Device Code

For headless or SSH environments. Displays a user_code to enter at a verification URL.

auth:
  type: oauth2-device
  clientId: my-cli-app
  deviceAuthUrl: https://auth.provider.com/device/code
  tokenUrl: https://auth.provider.com/token
  scopes: ["read"]

Commands

CommandDescription
/mcpShow all MCP servers with status
/mcp add [name]Add a new MCP server
/mcp remove [name]Remove an MCP server
/mcp restart [name]Restart an MCP connection
/mcp auth [name]Re-authenticate with an MCP server
/mcp tools [name]List tools provided by an MCP server

Status Display

Running /mcp shows a status table for all configured servers:

MCP Servers
───────────────────────────────────────────────────
  github         stdio    connected   authenticated   12 tools   2ms
  filesystem     stdio    connected   —               8 tools    1ms
  custom-api     http     connected   authenticated   5 tools    45ms
  legacy-srv     sse      error       expired         0 tools    —

Each server displays:

  • Connection state — connected, disconnected, error
  • Auth state — authenticated, expired, pending, or — (no auth required)
  • Tools count — number of available tools
  • Last ping — latency to the server

OAuth Flows

Authorization Code (Browser)

  1. Armament starts a local HTTP server on redirectPort
  2. Opens the authUrl in your default browser
  3. You authenticate and grant consent
  4. The browser redirects back to the local server with an auth code
  5. Armament exchanges the code for tokens
  6. Tokens are cached in ~/.armament/auth/ and refreshed automatically

Device Code (Headless)

  1. Armament requests a device code from deviceAuthUrl
  2. Displays the user_code and verification URL in the terminal
  3. You visit the URL on any device and enter the code
  4. Armament polls the token endpoint until authorized
  5. Tokens are cached and refreshed

Client Credentials (Automatic)

  1. Armament sends client ID and secret to tokenUrl
  2. Receives an access token
  3. Tokens are refreshed before expiry — no user interaction

Example Configurations

GitHub + Filesystem + Custom API

mcp:
  github:
    transport: stdio
    command: npx
    args: ["-y", "@modelcontextprotocol/server-github"]
    env:
      GITHUB_TOKEN: ${GITHUB_TOKEN}

  filesystem:
    transport: stdio
    command: npx
    args: ["-y", "@modelcontextprotocol/server-filesystem", "~/projects"]

  analytics:
    transport: streamable-http
    url: https://analytics.company.com/mcp
    auth:
      type: oauth2-client
      clientId: armament-prod
      clientSecret: ${ANALYTICS_SECRET}
      tokenUrl: https://auth.company.com/token
      scopes: ["analytics.read"]

Slack + Database

mcp:
  slack:
    transport: stdio
    command: npx
    args: ["-y", "@modelcontextprotocol/server-slack"]
    env:
      SLACK_BOT_TOKEN: ${SLACK_BOT_TOKEN}

  postgres:
    transport: streamable-http
    url: https://db-mcp.internal.com/v1
    auth:
      type: bearer
      token: ${DB_MCP_TOKEN}

Per-Agent Tool Access

Restrict which agents can access which MCP tools:

agents:
  reviewer:
    mcp: [github]
  deployer:
    mcp: [github, slack]
  researcher:
    mcp: [analytics, postgres]

Agents only see tools from their assigned MCP servers.