Skip to content
theirish81 edited this page Aug 27, 2026 · 5 revisions

Model Context Protocol (MCP)

Frags supports the Model Context Protocol (MCP). MCP is an open standard that enables LLMs to securely access and consume remote functions and tools. To utilize them, an MCP server must be running, which Frags will connect to and map to executable functions.

Enabling and using MCP servers involves two main steps:

  1. Configuring the server connections (at the runner/CLI level).
  2. Enabling specific MCP servers inside sessions (at the plan/session level).

CLI Configuration (tools.json)

To enable MCP servers in the CLI, create or update a tools.json file in the root directory of your project. Define your servers under the "mcpServers" block.

Frags supports two types of MCP servers:

  1. Local/Stdio Servers: Executables or scripts run locally on your system.
  2. Remote Servers: Servers hosted remotely, connected over HTTP/Streamable HTTP or SSE (Server-Sent Events).

Configuration Schema Example

Here is a comprehensive tools.json example demonstrating both local and remote servers, including standard configuration fields and advanced authentication parameters:

{
  "mcpServers": {
    "local-toolbox": {
      "command": "toolbox-binary",
      "args": [
        "--stdio",
        "--profile",
        "default"
      ],
      "env": {
        "DB_PROJECT": "my-local-project",
        "DEBUG": "true"
      },
      "cwd": "/path/to/working/dir",
      "disabled": false
    },
    "remote-service": {
      "url": "https://mcp.example.com/mcp",
      "transport": "sse",
      "headers": {
        "x-custom-origin": "frags-client"
      },
      "disabled": false,
      "client_id": "your-oauth-client-id",
      "client_secret": "your-oauth-client-secret",
      "authorization_url": "https://auth.example.com/oauth/authorize",
      "token_url": "https://auth.example.com/oauth/token"
    }
  }
}

Server Configuration Parameters

Field Name Type Description
command string The executable/command name to run for local stdio-based servers.
args array Command-line arguments passed to the local command.
env object Environment variables injected into the local process.
cwd string Working directory in which the local process is spawned.
url string The endpoint URL for a remote SSE or Streamable HTTP server.
transport string The HTTP transport protocol. Can be "sse" or omitted (defaults to Streamable HTTP with an SSE fallback).
headers object Custom HTTP headers sent with the requests to the remote server.
disabled boolean If set to true, Frags will completely ignore this server.
token string A static API key or Personal Access Token (PAT). Injects "Authorization: Bearer <token>" and bypasses the OAuth browser flow.
client_id string The Client ID for OAuth2 authentication (defaults to "frags-client").
client_secret string The Client Secret for OAuth2 authentication.
authorization_url string Explicit OAuth2 authorization endpoint. Bypasses discovery if set.
token_url string Explicit OAuth2 token exchange endpoint. Bypasses discovery if set.
pre_authorized_oauth object Pre-configured authentication token result structure (used to pre-populate authentication cache).

MCP Authentication

Frags provides native, secure, and flexible ways to authorize requests with remote servers.

1. Static Authentication (API Keys / PATs)

For quick integrations or systems that use Personal Access Tokens:

  • The token Property: Configure "token": "your_api_token" inside your server block. Frags will automatically inject this as an Authorization: Bearer your_api_token header and skip any OAuth flow.
  • Manual Headers: Alternatively, you can directly set custom headers in the "headers" block. If an "Authorization" header is detected inside the "headers" object, Frags skips all automatic authentication.

2. Native OAuth2 Authentication

For remote MCP servers implementing the Model Context Protocol OAuth 2.1 flow, Frags performs automated, secure 3-legged authorization.

Auto-Discovery

Frags queries the remote server to find the appropriate authorization and token endpoints dynamically via:

  • OAuth2 metadata discovery (RFC 8414)
  • Resource endpoint probing (RFC 9728)

If your remote server uses non-standard routes, you can bypass discovery by explicitly defining authorization_url and token_url in tools.json.

Interactive Browser Flow

If no valid token is found:

  1. Frags initializes an interactive flow and starts a temporary local HTTP server listening on http://localhost:9999/callback (the default callback URL).
  2. It automatically opens your default system browser to the server's authorization screen.
  3. Once authorized in the browser, the callback server captures the authorization code, exchanges it for Access and Refresh tokens, and safely terminates.
  4. Tokens are cached securely inside ./tokens.json with restrictive 0600 permissions.
  5. Transparent Background Refresh: For all subsequent runs, Frags checks ./tokens.json. If a token has expired, Frags will transparently refresh it in the background using the stored refresh token prior to communicating with the server.

Non-Interactive / Headless Mode

When running inside containers, virtual machines, CI/CD pipelines, or headless servers where a browser is unavailable:

  • Set the environment variable OAUTH_DISABLED=true (or configure it in your .env or application config file).
  • When set, Frags switches to headless mode (NewEmptyOauthProvider(true)), uses a temporary InMemoryCache, and completely disables browser launches and callback port listening.
  • If no valid token is found in memory or configured directly, the connection will fail immediately instead of blocking.

Session Activation

Once configured, servers are registered with Frags. However, to prevent context bloat and ensure security, servers must be explicitly enabled per session in your session configuration (YAML file).

Use the tools list in your sessions to allow access to the MCP server:

sessions:
  code_review:
    prePrompt: "Analyze the open pull requests."
    prompt: "Highlight security vulnerabilities or missing tests."
    tools:
      - name: github-server # Must match the key configured in tools.json
        type: mcp

Restricting Access (Allowlisting)

You can limit which specific remote tools an LLM can invoke by setting an allowlist array on the session tool:

sessions:
  code_review:
    prompt: "Check PR changes."
    tools:
      - name: github-server
        type: mcp
        allowlist:
          - github_view_pr
          - github_list_comments

Go API (Programmatic Usage)

If integrating Frags into your own Go applications, you can manage MCP tools and configure custom OAuth flows programmatically.

Standard MCP Connection

To establish connections to an MCP server:

import (
    "context"
    "github.com/fragshq/frags"
)

// Instantiate and connect to standard stdio or remote MCP servers
mcpTool := frags.NewMcpTool(name, serverConfig)
if err := mcpTool.Connect(ctx, logger); err != nil {
    return err
}

// Convert tools to executable functions
functions, err := mcpTool.AsFunctions(ctx)
if err != nil {
    return err
}

// Register with your AI engine
ai.SetFunctions(functions)

Customizing OAuth2 Programmatically

You can pass custom OAuth providers and cache implementations when setting up your programmatic tools. This is ideal for managing headless vs interactive environments:

import (
    "github.com/fragshq/frags"
    "github.com/fragshq/frags/mcpauth"
)

mcpTools := toolsConfig.McpServers.McpTools()

if oauthDisabled {
    // Non-interactive headless mode: InMemoryCache, no browser flow
    mcpTools.WithOAuthProvider(
        mcpauth.NewEmptyOauthProvider(true).WithCache(mcpauth.NewInMemoryCache()),
    )
} else {
    // Interactive mode: Persistent file cache, local callback flow
    oauthCache, err := mcpauth.NewFsOauthCache("./tokens.json")
    if err != nil {
        log.Fatalf("failed to load token cache: %v", err)
    }
    mcpTools.WithOAuthProvider(
        mcpauth.NewEmptyOauthProvider(false).WithCache(oauthCache),
    )
}

// Establish connections and negotiate tools
if err := mcpTools.Connect(ctx, logger); err != nil {
    log.Fatalf("failed to connect to MCP servers: %v", err)
}

Clone this wiki locally