Skip to content

Instantly share code, notes, and snippets.

@sinelaw
Created December 15, 2025 20:37
Show Gist options
  • Select an option

  • Save sinelaw/7eed0f08cae7df54b0357aa4395f825e to your computer and use it in GitHub Desktop.

Select an option

Save sinelaw/7eed0f08cae7df54b0357aa4395f825e to your computer and use it in GitHub Desktop.
A guide for integrating new editors with the AMP protocol, based on the `amp.nvim` implementation.

AMP Protocol Quick Reference

This document provides a guide for integrating new editors with the AMP protocol, based on the amp.nvim implementation.

Overview

The AMP integration is based on a WebSocket protocol. One editor acts as a server (in the case of amp.nvim, this is Neovim itself), and other tools or editor integrations act as clients.

A client connects to the server to send requests (like reading or editing a file) and receive responses and notifications (like when a file changes or the selection is updated).

Communication happens over a local WebSocket connection, and all messages are JSON payloads.

1. Server Discovery

To connect to the AMP server, a client must first discover the port and authentication token. This is done via a lockfile.

  • Lockfile Path: The server creates a lockfile at ~/.local/share/amp/ide/<port>.json. The client may need to scan a port range (e.g., 8000-8100) to find the active lockfile.

  • Lockfile Content: The lockfile is a JSON file containing the connection details.

    {
      "port": 8080,
      "authToken": "a-secret-auth-token"
    }

2. Connection and Authentication

Once the client has the port and authToken from the lockfile, it can establish a WebSocket connection.

  • Endpoint: The client initiates a WebSocket connection to ws://127.0.0.1:<port>?auth=<authToken>.
  • Handshake: The connection begins with a standard HTTP/1.1 GET request with an Upgrade: websocket header.
  • Authentication: The authToken from the lockfile must be sent as the auth query parameter in the connection URL. The server will reject connections with a missing or invalid token.

3. Message Framing

All communication after the initial handshake uses standard WebSocket TEXT frames, as defined in RFC 6455. Each TEXT frame contains a single JSON-encoded message payload.

4. Message Structure

All application messages are wrapped in a JSON object that indicates their type: a client request, a server response, or a server notification.

Client-to-Server (Requests)

Requests from the client to the server are for actions like reading a file or getting diagnostics.

  • Structure:
    {
      "clientRequest": {
        "id": "unique-request-id-123",
        "method": {
          "readFile": {
            "path": "/path/to/your/file.txt"
          }
        }
      }
    }
  • id: A unique identifier for the request, used to correlate it with a server response.
  • method: An object containing a single key, which is the name of the method being called (e.g., readFile), and its value is an object with the method's parameters.

Server-to-Client (Responses)

For every client request, the server sends a response.

  • Structure:
    {
      "serverResponse": {
        "id": "unique-request-id-123",
        "result": {
          "content": "The file content goes here."
        }
      }
    }
  • id: The id from the original clientRequest this response corresponds to.
  • result: The data returned by the method call. The structure of this object depends on the method.

Server-to-Client (Notifications)

The server can send notifications to the client to inform it of events, such as changes in the editor state. Notifications do not have an id as they are not in response to a specific request.

  • Structure:
    {
      "serverNotification": {
        "method": {
          "selectionChanged": {
            "path": "/path/to/your/file.txt",
            "start": { "line": 10, "col": 5 },
            "end": { "line": 10, "col": 12 }
          }
        }
      }
    }
  • method: The name of the notification and its associated data.

5. Supported Methods

The following are the core methods supported by the protocol.

Client Requests

  • readFile: Reads the content of a file visible to the editor.
    • Params: { "path": "string" }
    • Result: { "content": "string" }
  • editFile: Applies an edit to a file.
    • Params: { "path": "string", "start": "number", "end": "number", "newText": "string" } (Note: start and end are byte offsets)
    • Result: { "success": "boolean" }
  • getDiagnostics: Fetches diagnostic information (errors, warnings) for the current project.
    • Params: {}
    • Result: An array of diagnostic items.
  • openURI: Asks the editor to open a URI.
    • Params: { "uri": "string" }
    • Result: { "success": "boolean" }

Server Notifications

  • selectionChanged: Notifies the client that the user's selection has changed in a file.
    • Data: { "path": "string", "start": { "line": "number", "col": "number" }, "end": { "line": "number", "col": "number" } }
  • visibleFilesChanged: Notifies the client of the files currently visible in the editor.
    • Data: { "files": ["/path/to/file1.txt", "/path/to/file2.ts"] }

Example Workflow

  1. Client starts: The client scans for ~/.local/share/amp/ide/*.json.
  2. Client finds lockfile: It reads ~/.local/share/amp/ide/8080.json and gets the port (8080) and authToken.
  3. Client connects: It opens a WebSocket connection to ws://127.0.0.1:8080?auth=<token>.
  4. Client requests file: It sends a clientRequest for readFile.
    { "clientRequest": { "id": "req-1", "method": { "readFile": { "path": "README.md" } } } }
  5. Server responds: The server reads the file and sends a serverResponse.
    { "serverResponse": { "id": "req-1", "result": { "content": "# Amp" } } }
  6. User changes selection in editor: The server sends a serverNotification for selectionChanged.
    { "serverNotification": { "method": { "selectionChanged": { ... } } } }
  7. Client disconnects: The WebSocket connection is closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment