Connecting to the server

View as Markdown

M-Files Server speaks native gRPC over HTTP/2. Every service of the API is served on the same endpoint; there is no per-vault address. The vault is chosen when you log in (Authentication and sessions).

Endpoints

Deployment Address Transport
M-Files Cloud <vault-host>:443, for example contoso.cloudvault.m-files.com:443 TLS, public certificate
On-premises, default <server>:7766 Plain HTTP/2 (h2c) unless TLS is enabled
On-premises, TLS enabled <server>:7766 TLS with the server certificate configured in M-Files

Deployments compares the two in one table.

Method path. Every call is an HTTP/2 POST to /MFiles.<Service>/<Method>, for example /MFiles.IRPCQueryVersion/QueryVersion. The package is MFiles and the service names are the wire names (IRPCSearch, IRPCObjectOperations). Stubs generated from the published .proto files produce these paths; you never write them by hand. On M-Files Cloud the path is used at the root of the vault host, with no prefix. A method the server does not have answers UNIMPLEMENTED.

On-premises: finding the port

The gRPC port is the registry value gRPCEndpoint (DWORD) under HKEY_LOCAL_MACHINE\SOFTWARE\Motive\M-Files\<version>\Server\MFServer. When the value is missing or invalid the server uses 7766. The server listens on all network interfaces on that port; open it in the firewall for remote clients.

Other ports derive from it unless set explicitly:

Port Default Registry value What
gRPC 7766 gRPCEndpoint The API endpoint described on this page.
mf-http-grpc gateway gRPC + 1 (7767) GRPCWEBPORT mf-http-grpc, see HTTP access.
Local gRPC - - For M-Files' own processes on the server machine. Do not use it.

The local endpoint picks a random free port when its default is taken and writes the port back to the registry, so its number is not stable.

Some deployments put the M-Files reverse proxy (Traefik) in front of the server. The proxy then accepts gRPC over TLS on its HTTPS entry points, routes the /MFiles path prefix to the server and marks the calls as remote (see mfiles-is-remote-call in Call metadata). Use the address and certificate of the proxy.

TLS

M-Files Cloud always uses TLS with a publicly trusted certificate. Use your gRPC library's default TLS credentials.

On-premises the endpoint is plain HTTP/2 until an administrator enables TLS. TLS is enabled and its certificate installed with SetServerEndpointSettings (use_tls and one certificate with its private key; the server supports a single certificate). The server stores the settings in its master database and restarts the endpoint. GetServerEndpointSettings shows the current state. The server does not request client certificates.

A plain endpoint carries passwords, tokens and session IDs unencrypted. Use it only on a trusted network or for local development.

Trusting the certificate. The client must trust the CA that issued the server certificate, and the certificate's names must match the host name you connect to. M-Files' own Windows clients trust the Windows "Trusted Root Certification Authorities" store, so a certificate from an enterprise CA that is deployed there works for them without further setup. For a self-signed or private-CA certificate, give your gRPC client the CA certificate in PEM format:

Language How to trust a PEM CA file
Python (grpcio) grpc.ssl_channel_credentials(root_certificates=pem_bytes)
Go credentials.NewClientTLSFromFile(caFile, "")
Node (@grpc/grpc-js) grpc.credentials.createSsl(fs.readFileSync(caFile))
C# (Grpc.Net.Client) Install the CA in the machine's trust store, or validate the server certificate against it in HttpClientHandler.ServerCertificateCustomValidationCallback

The Python helper of the samples creates its channel like this (MFILES_CA_CERT points to the PEM file):

options = [("grpc.max_receive_message_length", MAX_RECEIVE_MESSAGE_BYTES),
           ("grpc.max_send_message_length", MAX_SEND_MESSAGE_BYTES)]
if config.tls:
    root_certificates = Path(config.ca_cert).read_bytes() if config.ca_cert else None
    credentials = grpc.ssl_channel_credentials(root_certificates=root_certificates)
    self._channel = grpc.secure_channel(config.address, credentials, options=options)
else:
    self._channel = grpc.insecure_channel(config.address, options=options)
self.channel = grpc.intercept_channel(self._channel, _MetadataInterceptor(self))

Source: python/mfiles_client.py

HTTP/2

Native gRPC needs HTTP/2 all the way to the server. With TLS, the client negotiates h2 with ALPN, which gRPC libraries do by default. Without TLS, the server expects HTTP/2 with prior knowledge (h2c); gRPC libraries do this when you create an insecure channel. A proxy or load balancer between client and server must forward HTTP/2 and response trailers, because the gRPC status and the M-Files error details travel in trailers (Errors).

Message size limits

Limit Server default Registry value (...\Server\MFServer)
Request message the server accepts 48 MiB (50 331 648 bytes) gRPCMaxMessageLength
Response message the server sends No limit (2 GiB - 1) gRPCMaxResponseLength
Metadata (headers or trailers) of a call 512 KiB gRPCMaxMetadataSize

A request over the server's limit fails with RESOURCE_EXHAUSTED and the message SERVER: Received message larger than max (51380234 vs. 50331648).

Most gRPC libraries accept responses of at most 4 MiB by default. M-Files responses can be larger, for example a 4 MiB file block plus its framing, or a large search result: such a call fails on the client with RESOURCE_EXHAUSTED and CLIENT: Received message larger than max (4194309 vs. 4194304). Do what M-Files' own client does, and what the samples do: accept responses of any size, and send requests up to the server's limit (48 MiB unless the administrator changed it):

Language No receive limit Send limit
Python channel option grpc.max_receive_message_length = -1 grpc.max_send_message_length
Go grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt32)) grpc.MaxCallSendMsgSize(n)
C# (Grpc.Net.Client) GrpcChannelOptions.MaxReceiveMessageSize = null MaxSendMessageSize
Node channel option grpc.max_receive_message_length = -1 grpc.max_send_message_length

Files larger than a single message are transferred in blocks; see Files.

HTTP/2 keepalive pings (not the session)

The server closes connections whose client sends HTTP/2 keepalive pings more often than every 5 seconds while no data flows (registry value gRPCMinPingIntervalMilliseconds, default 5000). M-Files' own clients ping every 10 seconds, wait 5 seconds for the answer, and ping only while a call is active. If you enable keepalive in your client, use an interval of 10 seconds or more.

HTTP/2 keepalive only keeps the connection open. The M-Files session expires on its own schedule unless you call KeepAlive; see Authentication and sessions.

Is the server reachable?

QueryVersion needs no session and no metadata. It is the cheapest check that the address, TLS and HTTP/2 path work:

/MFiles.IRPCQueryVersion/QueryVersion   request {}   ->   server_version: 7318397729964032

server_version is a packed 64-bit version: major, minor, build and revision, 16 bits each, from the most significant end. 7318397729964032 is 26.11.16645.0:

Part Bits Value
major v >> 48 26
minor (v >> 32) & 0xFFFF 11
build (v >> 16) & 0xFFFF 16645
revision v & 0xFFFF 0
/// <summary>
/// QueryVersion packs a version into 64 bits: major, minor, build and revision, 16 bits each.
/// </summary>
public static string DecodeVersion(ulong version) =>
    $"{version >> 48}.{(version >> 32) & 0xFFFF}.{(version >> 16) & 0xFFFF}.{version & 0xFFFF}";

Source: csharp/Recipes/Connect.cs

GetServerCapabilities is also anonymous and tells which optional features the server has; see Versions and compatibility.

If the check fails:

Status Usual cause
UNAVAILABLE Wrong host or port, firewall, an untrusted certificate, or a TLS client against a plain endpoint (Tls handshake failed).
UNIMPLEMENTED A plain (non-TLS) client against M-Files Cloud (Received http2 header with status: 404), a path that reached something other than M-Files Server, or a proxy that rewrote the path.
RESOURCE_EXHAUSTED A message size limit; see above.