Base Protocol Specification - 0.9
Base Protocol
The purpose of the base protocol is to create an abstraction of common editor extensibility patterns into its own specification, independently of the presence of a language server powering such extension. In particular, concepts such as server and client capabilities, the initialization and shutdown request, and the structure of requests and notifications, were originally part of the language server protocol, but there is nothing about them that should be exclusive to language service extensions.
A motivating example is the Build Server Protocol. As its specification describes, all notifications and requests are defined using the base definitions of LSP, and messages such InitializeBuild
, OnBuildInitialized
, and OnBuildExit
all match almost exactly with their LSP counterparts. By implementing the base protocol, a server can support multiple protocol specifications without having to reimplement the “common boilerplate” that all of them share.
Do remark that the base protocol is currently under experimental construction and subject to breaking changes. Its future development will depend on feedback from the community and initial implementors of the protocol.
Header Part
The base protocol consists of a header and a content part (comparable to HTTP). The header and content part are separated by a ‘\r\n’.
The header part consists of header fields. Each header field is comprised of a name and a value, separated by ‘: ‘ (a colon and a space). The structure of header fields conform to the HTTP semantic. Each header field is terminated by ‘\r\n’. Considering the last header field and the overall header itself are each terminated with ‘\r\n’, and that at least one header is mandatory, this means that two ‘\r\n’ sequences always immediately precede the content part of a message.
Currently the following header fields are supported:
Header Field Name | Value Type | Description |
---|---|---|
Content-Length | number | The length of the content part in bytes. This header is required. |
Content-Type | string | The mime type of the content part. Defaults to application/vscode-jsonrpc; charset=utf-8 |
The header part is encoded using the ‘ascii’ encoding. This includes the ‘\r\n’ separating the header and content part.
Content Part
Contains the actual content of the message. The content part of a message uses JSON-RPC to describe requests, responses and notifications. The content part is encoded using the charset provided in the Content-Type field. It defaults to utf-8
, which is the only encoding supported right now. If a server or client receives a header with a different encoding than utf-8
it should respond with an error.
Example:
Content-Length: ...\r\n
\r\n
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
...
}
}
Capabilities
Not every server can support all features defined by a protocol. The base protocol therefore provides “capabilities”. A capability groups a set of features. A development tool and the server announce their supported features using capabilities. As an example, a development tool could announce support for document creation notifications, so that servers can perform their corresponding document synchronizations tasks.
The set of capabilities is exchanged between the client and server during the initialize request.
Note that the following list of capability identifiers are already used by the language server protocol and hence cannot be used in other protocols:
callHierarchyProvider
codeActionProvider
codeLensProvider
colorProvider
completionProvider
declarationProvider
definitionProvider
diagnosticProvider
documentFormattingProvider
documentHighlightProvider
documentLinkProvider
documentOnTypeFormattingProvider
documentRangeFormattingProvider
documentSymbolProvider
executeCommandProvider
experimental
foldingRangeProvider
general
hoverProvider
implementationProvider
inlayHintProvider
inlineValueProvider
linkedEditingRangeProvider
monikerProvider
notebookDocument
notebookDocumentSync
positionEncoding
referencesProvider
renameProvider
selectionRangeProvider
semanticTokensProvider
signatureHelpProvider
textDocument
textDocumentSync
typeDefinitionProvider
typeHierarchyProvider
window
workspace
workspaceSymbolProvider
Request, Notification and Response Ordering
Responses to requests should be sent in roughly the same order as the requests appear on the server or client side. So, for example, if a server providing unit testing features receives a testing/configureFramework
request and then a testing/configureProject
request, it will usually first return the response for the testing/configureFramework
and then the response for testing/configureProject
.
However, the server may decide to use a parallel execution strategy and may wish to return responses in a different order than the requests were received. The server may do so as long as this reordering doesn’t affect the correctness of the responses. For example, reordering the result of testing/configureFramework
and testing/configureProject
is allowed, as each of these requests usually won’t affect the output of the other. On the other hand, the server most likely should not reorder testing/testCreated
and testing/executeTest
requests, since test creation should happen before their execution.
Message Documentation
As mentioned previously, the base protocol defines a set of requests, responses and notifications. Each of those are documented using the following format:
- a header describing the request
- an optional Client capability section describing the client capability of the request. This includes the client capabilities property path and JSON structure.
- an optional Server Capability section describing the server capability of the request. This includes the server capabilities property path and JSON structure. Clients should ignore server capabilities they don’t understand (e.g. the initialize request shouldn’t fail in this case).
- an optional Registration Options section describing the registration option if the request or notification supports dynamic capability registration. See the register and unregister request for how this works in detail.
- a Request section describing the format of the request sent. The method is a string identifying the request, the parameters are documented using a TypeScript interface. It is also documented whether the request supports work done progress and partial result progress.
- a Response section describing the format of the response. The result item describes the returned data in case of a success. The optional partial result item describes the returned data of a partial result notification. The
error.data
describes the returned data in case of an error. Please remember that in case of a failure the response already contains anerror.code
and anerror.message
field. These fields are only specified if the protocol forces the use of certain error codes or messages. In cases where the server can decide on these values freely they aren’t listed here.
JSON structures
The base protocol uses request, response, and notification objects as specified in the JSON-RPC protocol. It currently does not support JSON-RPC batch messages; protocol clients and servers must not send JSON-RPC requests.
Base Types
The base protocol uses the following definitions for integers, unsigned integers, decimal numbers, objects and arrays:
/**
* Defines an integer number in the range of -2^31 to 2^31 - 1.
*/
export type integer = number;
/**
* Defines an unsigned integer number in the range of 0 to 2^31 - 1.
*/
export type uinteger = number;
/**
* Defines a decimal number. Since decimal numbers are very
* rare in the base protocol specification, we denote the
* exact range with every decimal using the mathematics
* interval notation (e.g. [0, 1] denotes all decimals d with
* 0 <= d <= 1).
*/
export type decimal = number;
/**
* Base Protocol any type.
*/
export type BaseAny = BaseObject | BaseArray | string | integer | uinteger |
decimal | boolean | null;
/**
* Base Protocol object definition.
*/
export type BaseObject = { [key: string]: BaseAny };
/**
* Base Protocol arrays.
*/
export type BaseArray = BaseAny[];
URI
URI’s are transferred as strings. The URI’s format is defined in https://tools.ietf.org/html/rfc3986
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| _____________________|__
/ \ / \
urn:example:animal:ferret:nose
We also maintain a node module to parse a string into scheme
, authority
, path
, query
, and fragment
URI components. The GitHub repository is https://github.com/Microsoft/vscode-uri the npm module is https://www.npmjs.com/package/vscode-uri.
Many of the interfaces contain fields that correspond to the URI of a document. For clarity, the type of such a field is declared as a DocumentUri
. Over the wire, it will still be transferred as a string, but this guarantees that the contents of that string can be parsed as a valid URI.
type DocumentUri = string;
There is also a tagging interface for normal non document URIs. It maps to a string
as well.
type URI = string;
Regular Expressions
Regular expressions are a powerful tool and there are actual use cases for them in protocols like LSP. However the downside with them is that almost every programming language has its own set of regular expression features so the base specification can not simply refer to them as a regular expression.
For example, LSP uses a two step approach to support regular expressions:
- the client will announce which regular expression engine it will use. This will allow servers that are written for a very specific client make full use of the regular expression capabilities of the client.
- the specification will define a set of regular expression features that should be supported by a client. Instead of writing a new specification LSP will refer to the ECMAScript Regular Expression specification and remove features from it that are not necessary in the context of LSP or hard to implement for other clients.
The following client capability is used to announce a client’s regular expression engine
- property path (optional):
general.regularExpressions
- property type:
RegularExpressionsClientCapabilities
defined as follows:
/**
* Client capabilities specific to regular expressions.
*/
export interface RegularExpressionsClientCapabilities {
/**
* The engine's name.
*/
engine: string;
/**
* The engine's version.
*/
version?: string;
}
Enumerations
The base protocol supports two kind of enumerations: (a) integer based enumerations and (b) strings based enumerations. Integer based enumerations usually start with 1
. If appropriate the value set of an enumeration is announced by the defining side (e.g. client or server) and transmitted to the other side during the initialize handshake.
As an example, consider a printSymbol
request that uses a PrintFormat
enumeration. The client could announce its supported printing formats via printing.format
property:
/**
* Capabilities specific to the `printSymbol` request.
*/
print: {
format: [ "json", "compact", "checkstyle" ]
...
}
To support the evolution of enumerations the using side of an enumeration shouldn’t fail on an enumeration value it doesn’t know. It should simply ignore it as a value it can use and try to do its best to preserve the value on round trips. Lets look at the PrintFormat
enumeration as an example again: if in a future version of the protocol an additional "html"
format is added and is now announced by a client, an (older) server not knowing about the value should not fail but simply ignore the value as a usable printing format.
Abstract Message
A general message as defined by JSON-RPC. The language server protocol always uses “2.0” as the jsonrpc
version.
interface Message {
jsonrpc: string;
}
Request Message
A request message to describe a request between the client and the server. Every processed request must send a response back to the sender of the request.
interface RequestMessage extends Message {
/**
* The request id.
*/
id: integer | string;
/**
* The method to be invoked.
*/
method: string;
/**
* The method's params.
*/
params?: array | object;
}
Response Message
A Response Message sent as a result of a request. If a request doesn’t provide a result value the receiver of a request still needs to return a response message to conform to the JSON-RPC specification. The result property of the ResponseMessage should be set to null
in this case to signal a successful request.
interface ResponseMessage extends Message {
/**
* The request id.
*/
id: integer | string | null;
/**
* The result of a request. This member is REQUIRED on success.
* This member MUST NOT exist if there was an error invoking the method.
*/
result?: string | number | boolean | array | object | null;
/**
* The error object in case a request fails.
*/
error?: ResponseError;
}
interface ResponseError {
/**
* A number indicating the error type that occurred.
*/
code: integer;
/**
* A string providing a short description of the error.
*/
message: string;
/**
* A primitive or structured value that contains additional
* information about the error. Can be omitted.
*/
data?: string | number | boolean | array | object | null;
}
export namespace ErrorCodes {
// Defined by JSON-RPC
export const ParseError: integer = -32700;
export const InvalidRequest: integer = -32600;
export const MethodNotFound: integer = -32601;
export const InvalidParams: integer = -32602;
export const InternalError: integer = -32603;
/**
* This is the start range of JSON-RPC reserved error codes.
* It doesn't denote a real error code. No error codes of the
* base protocol should be defined between the start and end
* range. For backwards compatibility the `ServerNotInitialized`
* and the `UnknownErrorCode` are left in the range.
*/
export const jsonrpcReservedErrorRangeStart: integer = -32099;
/**
* Error code indicating that a server received a notification or
* request before the server has received the `initialize` request.
*/
export const ServerNotInitialized: integer = -32002;
export const UnknownErrorCode: integer = -32001;
/**
* This is the end range of JSON-RPC reserved error codes.
* It doesn't denote a real error code.
*/
export const jsonrpcReservedErrorRangeEnd = -32000;
/**
* This is the start range of LSP reserved error codes.
* It doesn't denote a real error code.
*/
export const lspReservedErrorRangeStart: integer = -32899;
/**
* A request failed but it was syntactically correct, e.g the
* method name was known and the parameters were valid. The error
* message should contain human readable information about why
* the request failed.
*/
export const RequestFailed: integer = -32803;
/**
* The server cancelled the request. This error code should
* only be used for requests that explicitly support being
* server cancellable.
*/
export const ServerCancelled: integer = -32802;
/**
* The server detected that the content of a document got
* modified outside normal conditions. A server should
* NOT send this error code if it detects a content change
* in it unprocessed messages. The result even computed
* on an older state might still be useful for the client.
*
* If a client decides that a result is not of any use anymore
* the client should cancel the request.
*/
export const ContentModified: integer = -32801;
/**
* The client has canceled a request and a server as detected
* the cancel.
*/
export const RequestCancelled: integer = -32800;
/**
* This is the end range of LSP reserved error codes.
* It doesn't denote a real error code.
*/
export const lspReservedErrorRangeEnd: integer = -32800;
}
To avoid conflicts with the error codes taken by the language service protocol, other implementers of the base protocol must use error codes outside the range defined by lspReservedErrorRangeStart
and lspReservedErrorRangeEnd
.
Notification Message
A notification message. A processed notification message must not send a response back. They work like events.
interface NotificationMessage extends Message {
/**
* The method to be invoked.
*/
method: string;
/**
* The notification's params.
*/
params?: array | object;
}
$ Notifications and Requests
Notification and requests whose methods start with ‘$/’ are messages which are protocol implementation dependent and might not be implementable in all clients or servers. For example, if the server implementation uses a single threaded synchronous programming language then there is little a server can do to react to a $/cancelRequest
notification. If a server or client receives notifications starting with ‘$/’ it is free to ignore the notification. If a server or client receives a request starting with ‘$/’ it must error the request with error code MethodNotFound
(e.g. -32601
).
Cancellation Support ( )
The base protocol offers support for request cancellation. To cancel a request, a notification message with the following properties is sent:
Notification:
- method: ‘$/cancelRequest’
- params:
CancelParams
defined as follows:
interface CancelParams {
/**
* The request id to cancel.
*/
id: integer | string;
}
A request that got canceled still needs to return from the server and send a response back. It can not be left open / hanging. This is in line with the JSON-RPC protocol that requires that every request sends a response back. In addition it allows for returning partial results on cancel. If the request returns an error response on cancellation it is advised to set the error code to ErrorCodes.RequestCancelled
.
Progress Support ( )
The base protocol also offers support to report progress in a generic fashion. This mechanism can be used to report any kind of progress including work done progress (usually used to report progress in the user interface using a progress bar) and partial result progress to support streaming of results.
A progress notification has the following properties:
Notification:
- method: ‘$/progress’
- params:
ProgressParams
defined as follows:
type ProgressToken = integer | string;
interface ProgressParams<T> {
/**
* The progress token provided by the client or server.
*/
token: ProgressToken;
/**
* The progress data.
*/
value: T;
}
Progress is reported against a token. The token is different than the request ID which allows to report progress out of band and also for notification.
Work Done Progress
Work done progress is reported using the generic $/progress
notification. The value payload of a work done progress notification can be of three different forms.
Work Done Progress Begin
To start progress reporting a $/progress
notification with the following payload must be sent:
export interface WorkDoneProgressBegin {
kind: 'begin';
/**
* Mandatory title of the progress operation. Used to briefly inform about
* the kind of operation being performed.
*
* Examples: "Indexing" or "Linking dependencies".
*/
title: string;
/**
* Controls if a cancel button should show to allow the user to cancel the
* long running operation. Clients that don't support cancellation are
* allowed to ignore the setting.
*/
cancellable?: boolean;
/**
* Optional, more detailed associated progress message. Contains
* complementary information to the `title`.
*
* Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
* If unset, the previous progress message (if any) is still valid.
*/
message?: string;
/**
* Optional progress percentage to display (value 100 is considered 100%).
* If not provided infinite progress is assumed and clients are allowed
* to ignore the `percentage` value in subsequent in report notifications.
*
* The value should be steadily rising. Clients are free to ignore values
* that are not following this rule. The value range is [0, 100]
*/
percentage?: uinteger;
}
Work Done Progress Report
Reporting progress is done using the following payload:
export interface WorkDoneProgressReport {
kind: 'report';
/**
* Controls enablement state of a cancel button. This property is only valid
* if a cancel button got requested in the `WorkDoneProgressBegin` payload.
*
* Clients that don't support cancellation or don't support control the
* button's enablement state are allowed to ignore the setting.
*/
cancellable?: boolean;
/**
* Optional, more detailed associated progress message. Contains
* complementary information to the `title`.
*
* Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
* If unset, the previous progress message (if any) is still valid.
*/
message?: string;
/**
* Optional progress percentage to display (value 100 is considered 100%).
* If not provided infinite progress is assumed and clients are allowed
* to ignore the `percentage` value in subsequent in report notifications.
*
* The value should be steadily rising. Clients are free to ignore values
* that are not following this rule. The value range is [0, 100]
*/
percentage?: uinteger;
}
Work Done Progress End
Signaling the end of a progress reporting is done using the following payload:
export interface WorkDoneProgressEnd {
kind: 'end';
/**
* Optional, a final message indicating to, for example, indicate the outcome
* of the operation.
*/
message?: string;
}
Initiating Work Done Progress
Work Done progress can be initiated in two different ways:
- by the sender of a request (mostly clients) using the predefined
workDoneToken
property in the requests parameter literal. The document will refer to this kind of progress as client initiated progress. - by a server using the request
window/workDoneProgress/create
. The document will refer to this kind of progress as server initiated progress.
Client Initiated Progress
Consider a client sending a build/deploy
request to a server that can compile and build applications and the client accepts work done progress reporting on that request. To signal this to the server, the client would add a workDoneToken
property to the reference request parameters:
{
"project": {
"guid": "A083-41A9-A0E8"
},
"context": {
"destinationDirectory": "/prod"
},
// The token used to report work done progress.
"workDoneToken": "1d546990-40a3-4b77-b134-46622995f6ae"
}
The corresponding type definition for the parameter property looks like this:
export interface WorkDoneProgressParams {
/**
* An optional token that a server can use to report work done progress.
*/
workDoneToken?: ProgressToken;
}
A server uses the workDoneToken
to report progress for the specific build/deploy
. For the above request, the $/progress
notification parameters look like this:
{
"token": "1d546990-40a3-4b77-b134-46622995f6ae",
"value": {
"kind": "begin",
"title": "Deploying project#A083-41A9-A0E8",
"cancellable": false,
"message": "Processing projectConfig.json",
"percentage": 0
}
}
The token received via the workDoneToken
property in a request’s param literal is only valid as long as the request has not send a response back.
There is no specific client capability signaling whether a client will send a progress token per request. The reason for this is that this is in many clients not a static aspect and might even change for every request instance for the same request type. So the capability is signal on every request instance by the presence of a workDoneToken
property.
To avoid that clients set up a progress monitor user interface before sending a request but the server doesn’t actually report any progress a server needs to signal general work done progress reporting support in the corresponding server capability. For the above example a server would signal such a support by setting the deployProvider
property in the server capabilities as follows:
{
"build.deployProvider": {
"workDoneProgress": true
}
}
The corresponding type definition for the server capability looks like this:
export interface WorkDoneProgressOptions {
workDoneProgress?: boolean;
}
Server Initiated Progress
Servers can also initiate progress reporting using the window/workDoneProgress/create
request. This is useful if the server needs to report progress outside of a request (for example, the server needs to re-index a database). The token can then be used to report progress using the same notifications used as for client initiated progress. The token provided in the create request should only be used once (e.g. only one begin, many report and one end notification should be sent to it).
To keep the protocol backwards compatible servers are only allowed to use window/workDoneProgress/create
request if the client signals corresponding support using the client capability window.workDoneProgress
which is defined as follows:
/**
* Window specific client capabilities.
*/
window?: {
/**
* Whether client supports server initiated progress using the
* `window/workDoneProgress/create` request.
*/
workDoneProgress?: boolean;
};
TraceValue
A TraceValue
represents the level of verbosity with which the server systematically reports its execution trace using $/logTrace notifications.
The initial trace value is set by the client at initialization and can be modified later using the $/setTrace notification.
export type TraceValue = 'off' | 'messages' | 'verbose';
Lifecycle Messages
The current protocol specification defines that the lifecycle of a server is managed by the client (e.g. a tool like VS Code or Emacs). It is up to the client to decide when to start (process-wise) and when to shutdown a server.
Initialize Request ()
The initialize request is sent as the first request from the client to the server. If the server receives a request or notification before the initialize
request it should act as follows:
- For a request the response should be an error with
code: -32002
. The message can be picked by the server. - Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request.
Until the server has responded to the initialize
request with an InitializeResult
, the client must not send any additional requests or notifications to the server. In addition the server is not allowed to send any requests or notifications to the client until it has responded with an InitializeResult
, with the exception that during the initialize
request the server is allowed to send the notifications window/showMessage
, window/logMessage
and telemetry/event
as well as the window/showMessageRequest
request to the client. In case the client sets up a progress token in the initialize params (e.g. property workDoneToken
) the server is also allowed to use that token (and only that token) using the $/progress
notification sent from the server to the client.
The initialize
request may only be sent once.
Request:
- method: ‘initialize’
- params:
InitializeParams
defined as follows:
interface InitializeParams extends WorkDoneProgressParams {
/**
* The process Id of the parent process that started the server. Is null if
* the process has not been started by another process. If the parent
* process is not alive then the server should exit (see exit notification)
* its process.
*/
processId: integer | null;
/**
* Information about the client
*/
clientInfo?: {
/**
* The name of the client as defined by the client.
*/
name: string;
/**
* The client's version as defined by the client.
*/
version?: string;
};
/**
* The locale the client is currently showing the user interface
* in. This must not necessarily be the locale of the operating
* system.
*
* Uses IETF language tags as the value's syntax
* (See https://en.wikipedia.org/wiki/IETF_language_tag)
*/
locale?: string;
/**
* User provided initialization options.
*/
initializationOptions?: BaseAny;
/**
* The capabilities provided by the client (editor or tool)
*/
capabilities: {};
/**
* The initial trace setting. If omitted trace is disabled ('off').
*/
trace?: TraceValue;
}
Response:
- result:
InitializeResult
defined as follows:
interface InitializeResult {
/**
* The capabilities the server provides.
*/
capabilities: {};
/**
* Information about the server.
*/
serverInfo?: {
/**
* The name of the server as defined by the server.
*/
name: string;
/**
* The server's version as defined by the server.
*/
version?: string;
};
}
- error.data:
interface InitializeError {
/**
* Indicates whether the client execute the following retry logic:
* (1) show the message provided by the ResponseError to the user
* (2) user selects retry or cancel
* (3) if user selected retry the initialize method is sent again.
*/
retry: boolean;
}
Note that capabilities
is specified as an empty object in both InitializeParams
and InitializeResult
, and are left open for each implementation of the base protocol to define accordingly. However, in order to avoid conflicts with properties used by LSP, these cannot include any of the property names listed in the above capabilities section.
Initialized Notification ()
The initialized notification is sent from the client to the server after the client received the result of the initialize
request but before the client is sending any other request or notification to the server. The server can use the initialized
notification, for example, to dynamically register capabilities. The initialized
notification may only be sent once.
Notification:
- method: ‘initialized’
- params:
InitializedParams
defined as follows:
interface InitializedParams {
}
Register Capability ()
The client/registerCapability
request is sent from the server to the client to register for a new capability on the client side. Not all clients need to support dynamic capability registration. A client opts in via the dynamicRegistration
property on the specific client capabilities. A client can even provide dynamic registration for capability A but not for capability B.
The server must not register the same capability both statically through the initialize result and dynamically for the same document selector. If a server wants to support both static and dynamic registration it needs to check the client capability in the initialize request and only register the capability statically if the client doesn’t support dynamic registration for that capability.
Request:
- method: ‘client/registerCapability’
- params:
RegistrationParams
Where RegistrationParams
are defined as follows:
/**
* General parameters to register for a capability.
*/
export interface Registration {
/**
* The id used to register the request. The id can be used to deregister
* the request again.
*/
id: string;
/**
* The method / capability to register for.
*/
method: string;
/**
* Options necessary for the registration.
*/
registerOptions?: BaseAny;
}
export interface RegistrationParams {
registrations: Registration[];
}
Response:
- result: void.
- error: code and message set in case an exception happens during the request.
StaticRegistrationOptions
can be used to register a feature in the initialize result with a given server control ID to be able to un-register the feature later on.
/**
* Static registration options to be returned in the initialize request.
*/
export interface StaticRegistrationOptions {
/**
* The id used to register the request. The id can be used to deregister
* the request again. See also Registration#id.
*/
id?: string;
}
Unregister Capability ()
The client/unregisterCapability
request is sent from the server to the client to unregister a previously registered capability.
Request:
- method: ‘client/unregisterCapability’
- params:
UnregistrationParams
Where UnregistrationParams
are defined as follows:
/**
* General parameters to unregister a capability.
*/
export interface Unregistration {
/**
* The id used to unregister the request or notification. Usually an id
* provided during the register request.
*/
id: string;
/**
* The method / capability to unregister for.
*/
method: string;
}
export interface UnregistrationParams {
unregistrations: Unregistration[];
}
Response:
- result: void.
- error: code and message set in case an exception happens during the request.
SetTrace Notification ()
A notification that should be used by the client to modify the trace setting of the server.
Notification:
- method: ‘$/setTrace’
- params:
SetTraceParams
defined as follows:
interface SetTraceParams {
/**
* The new value that should be assigned to the trace setting.
*/
value: TraceValue;
}
LogTrace Notification ()
A notification to log the trace of the server’s execution.
The amount and content of these notifications depends on the current trace
configuration.
If trace
is 'off'
, the server should not send any logTrace
notification.
If trace
is 'messages'
, the server should not add the 'verbose'
field in the LogTraceParams
.
$/logTrace
should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage
notifications.
Notification:
- method: ‘$/logTrace’
- params:
LogTraceParams
defined as follows:
interface LogTraceParams {
/**
* The message to be logged.
*/
message: string;
/**
* Additional information that can be computed if the `trace` configuration
* is set to `'verbose'`
*/
verbose?: string;
}
Shutdown Request ()
The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit. Clients must not send any notifications other than exit
or requests to a server to which they have sent a shutdown request. Clients should also wait with sending the exit
notification until they have received a response from the shutdown
request.
If a server receives requests after a shutdown request those requests should error with InvalidRequest
.
Request:
- method: ‘shutdown’
- params: none
Response:
- result: null
- error: code and message set in case an exception happens during shutdown request.
Exit Notification ()
A notification to ask the server to exit its process.
The server should exit with success
code 0 if the shutdown request has been received before; otherwise with error
code 1.
Notification:
- method: ‘exit’
- params: none
Window Features
ShowMessage Notification ()
The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface.
Notification:
- method: ‘window/showMessage’
- params:
ShowMessageParams
defined as follows:
interface ShowMessageParams {
/**
* The message type. See {@link MessageType}.
*/
type: MessageType;
/**
* The actual message.
*/
message: string;
}
Where the type is defined as follows:
export namespace MessageType {
/**
* An error message.
*/
export const Error = 1;
/**
* A warning message.
*/
export const Warning = 2;
/**
* An information message.
*/
export const Info = 3;
/**
* A log message.
*/
export const Log = 4;
/**
* A debug message.
*
* @since 3.18.0
* @proposed
*/
export const Debug = 5;
}
export type MessageType = 1 | 2 | 3 | 4 | 5;
ShowMessage Request ()
The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client.
Client Capability:
- property path (optional):
window.showMessage
- property type:
ShowMessageRequestClientCapabilities
defined as follows:
/**
* Show message request client capabilities
*/
export interface ShowMessageRequestClientCapabilities {
/**
* Capabilities specific to the `MessageActionItem` type.
*/
messageActionItem?: {
/**
* Whether the client supports additional attributes which
* are preserved and sent back to the server in the
* request's response.
*/
additionalPropertiesSupport?: boolean;
};
}
Request:
- method: ‘window/showMessageRequest’
- params:
ShowMessageRequestParams
defined as follows:
interface ShowMessageRequestParams {
/**
* The message type. See {@link MessageType}
*/
type: MessageType;
/**
* The actual message
*/
message: string;
/**
* The message action items to present.
*/
actions?: MessageActionItem[];
}
Where the MessageActionItem
is defined as follows:
interface MessageActionItem {
/**
* A short title like 'Retry', 'Open Log' etc.
*/
title: string;
}
Response:
- result: the selected
MessageActionItem
|null
if none got selected. - error: code and message set in case an exception happens during showing a message.
LogMessage Notification ()
The log message notification is sent from the server to the client to ask the client to log a particular message.
Notification:
- method: ‘window/logMessage’
- params:
LogMessageParams
defined as follows:
interface LogMessageParams {
/**
* The message type. See {@link MessageType}
*/
type: MessageType;
/**
* The actual message
*/
message: string;
}
Telemetry Notification ()
The telemetry notification is sent from the server to the client to ask the client to log a telemetry event. The protocol doesn’t specify the payload since no interpretation of the data happens in the protocol. Most clients even don’t handle the event directly but forward them to the extensions owing the corresponding server issuing the event.
Notification:
- method: ‘telemetry/event’
- params: ‘object’ | ‘array’;