Skip to content
Version 1.0.0

Connect an MCP server

Declare a local MCP server, get it approved by the administrator, and check that it responds.

An MCP server, or connector, gives the agent tools that are not its own. These tools follow the same rules as the others:

  • a session’s tools are set by the project policy before any read, and the administrator can remove one (security white paper V3, sections 5.1 and 5.2). A connector therefore starts only once approved by the administrator;
  • a connector runs in the same confinement as the session: no network, no secrets, and none of your workstation’s environment (security white paper V3, guarantee G05 and section 4.3).

Two forms of connector have no place in a session: a server reached over the network, and a command that downloads its program at startup.

The server is a process started for the session, which the agent talks to over its standard input and output. Declare it in ~/.lemniscate/workstation.yaml:

name: Local Config
version: 1.0.0
mcpServers:
- name: analyse-statique
command: /opt/mcp/bin/analyse-statique
args:
- "--format"
- json
env:
LOG_LEVEL: debug

name and command are required. args, env and cwd are not; a relative cwd is resolved from the workspace root.

command refers to a program that is already installed. A command that fetches its program at execution time has no network destination to reach, and its contents would change without its declaration changing.

The server does not receive your workstation’s environment: not your tokens, not your API keys, not your SSH agent’s address. It receives what the declaration names in env, written in clear text. This block carries settings, not secrets: the agent and its tools hold no secrets (security white paper V3, section 4.3).

The administrator approves a connector in the policy, using two pieces of information: its name, and the fingerprint of its startup declaration. The fingerprint covers the command and its arguments, in order. It covers neither the name nor the env block.

  1. Declare the connector as above and open a session. As long as it is not approved, it does not start, and the refusal gives its fingerprint:

    The connector "analyse-statique" is not approved by your organization's policy. Its fingerprint here is sha256:<empreinte>. It will not start.
  2. Pass the name and the fingerprint to the project administrator.

  3. The administrator adds the entry to the policy’s approvedConnectors field. In the console, this field is edited in the Advanced section of the Policy tab; see What stays in the JSON document.

{
"approvedConnectors": [
{
"name": "analyse-statique",
"fingerprint": "sha256:0000000000000000000000000000000000000000000000000000000000000000"
}
]
}

A fingerprint is written as sha256: followed by 64 hexadecimal characters. An entry without a fingerprint, or in another form, causes the entire policy to be refused at installation.

What follows from this:

  • changing command or args changes the fingerprint, and the connector no longer starts until the new one is approved. The refusal then says that the fingerprint does not match the one approved for that name;
  • an empty list approves no connector;
  • the console’s External connectors (MCP servers) rule, set to Forbidden, prevents any connector from starting, approved or not.

The fingerprint attests to the declaration, not to the code of the program that is started.

connectionTimeout is expressed in milliseconds and defaults to 20,000. A server that is slow to start needs a higher value:

name: Local Config
version: 1.0.0
mcpServers:
- name: serveur-lent
command: /opt/mcp/bin/serveur
connectionTimeout: 60000

This field applies on both sides: lemni and the IDE open the connection through the same code.

A server can live in a file of its own, outside workstation.yaml, in the ~/.lemniscate/mcpServers/ folder of your personal configuration. Two formats exist, and they are not read by the same surfaces.

The JSON file is read by the IDE and by lemni:

{
"mcpServers": {
"analyse-statique": {
"command": "/opt/mcp/bin/analyse-statique",
"args": ["--format", "json"],
"env": { "LOG_LEVEL": "debug" }
}
}
}

The YAML file is read by the IDE only. It carries its own header and exactly one server:

name: serveur-analyse
version: 0.0.1
mcpServers:
- name: analyse-statique
command: /opt/mcp/bin/analyse-statique

Servers declared this way are added to those in workstation.yaml: nothing is replaced. The same server declared in two places opens only one connection.

A connector declared in a repository does not start, whether it comes from a .lemniscate/mcpServers/ folder in the repository or from the mcpServers block of its .lemniscate/project.yaml file. The product names the declaration that was set aside. Content read from the repository adds no tools to the session (security white paper V3, section 5.2).

To use that connector, declare it in your own configuration and get it approved.

In the IDE, saving the file restarts the connection, but only if the command, the arguments or the environment have changed; renaming a server does not reconnect it.

The Settings → Tools screen lists the servers with a status dot and groups the tools each one exposes underneath it. A connection error appears there, and also shows up in the configuration loading errors. The process output is attached to the message.

In lemni, the /mcp command opens the list of connections and their status:

/mcp

One behavior difference worth knowing: in an interactive session, a server that fails leaves the rest working. In -p mode (single output), an MCP server failure makes startup fail.

The server’s tools join the agent’s tool list. In the IDE, they appear grouped under the server’s name and prefixed with it.

Each call is submitted to you before it runs. The project policy decides the rest: the administrator can remove a tool from the agent, by name, without redeployment (security white paper V3, section 5.1). See Set workstation policy from the console.

The prompts exposed by a server become / commands. Its resources become @ mentions, under an entry bearing the server’s name; this last capability exists only in the IDE.

The name is the identity. Two servers with the same name do not coexist: the second does not open a connection of its own.

The uses: form does not work here. The schema accepts it, but no server is resolved through that field. Declare the server in clear text, as above.