Connect an MCP server
Can’t find the MCP server you need in the market? Add it by hand, or package it for others.
Add it in Settings
Section titled “Add it in Settings”-
Settings → Plugins → MCP → the
⋯on the right → Add a stdio server. -
Fill in the command and arguments, separated by spaces:
Field Example Command npxArguments -y @modelcontextprotocol/server-filesystem /Users/me/code -
If it needs a key, add an environment variable under How it starts, and its environment on its card. Anything named like a secret (containing
KEY,TOKEN,SECRET,PASSWORDand so on) is stored encrypted Next release -
A new server starts out switched on. Once it’s filled in, check its card: it shows how many tools it provides when connected, or the error when not.
- Settings → Plugins → MCP → the
⋯on the right → Add an HTTP server. - Enter the URL and choose Streamable HTTP or SSE as the transport, per the server’s docs.
- A new server starts out switched on; once it’s filled in, check the status on its card.
Package it as an MCP bundle
Section titled “Package it as an MCP bundle”For a one-click install, make a folder with a .mcp.json describing the server and a manifest with its name and description.
Directoryplaywright/
Directory.lyra-plugin/
- plugin.json
- icon.svg optional
- .mcp.json
.mcp.json uses the same format as Claude Code. A local server takes a command and arguments:
{ "mcpServers": { "playwright": { "command": "npx", "args": ["-y", "@playwright/mcp@latest"] } }}A remote server takes a type and a url:
{ "mcpServers": { "deepwiki": { "type": "http", "url": "https://mcp.deepwiki.com/mcp" } }}Point the manifest’s mcpServers at the file:
{ "name": "playwright", "version": "1.0.0", "description": "Drive a browser through its accessibility tree", "mcpServers": ".mcp.json"}Values the user supplies Next release
Section titled “Values the user supplies ”For values like keys that each user has to supply, write a ${NAME} placeholder in .mcp.json — in env for a local server, in headers for a remote one.
{ "mcpServers": { "brave-search": { "command": "npx", "args": ["-y", "@brave/brave-search-mcp-server@latest"], "env": { "BRAVE_API_KEY": "${BRAVE_API_KEY}" } } }}{ "mcpServers": { "github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/", "headers": { "Authorization": "Bearer ${GITHUB_PERSONAL_ACCESS_TOKEN}" } } }}Then describe each placeholder in the manifest’s env, and Lyra asks for it in the interface after installing:
{ "name": "brave-search", "version": "1.0.0", "description": "Web search on Brave's own index", "mcpServers": ".mcp.json", "env": [ { "name": "BRAVE_API_KEY", "description": "Your Brave Search API key", "url": "https://brave.com/search/api/", "secret": true } ]}env field |
Purpose |
|---|---|
name |
The placeholder’s name |
description |
One line on what it is |
url |
Where to get one; shown as Get one |
secret |
Whether it’s secret. If left out, Lyra guesses from the name |
optional |
May be left empty; if it is, the variable isn’t passed at all |
Values come from what the user entered in Lyra first, then from their login shell’s environment. If a required value is missing, the server doesn’t start and its card lists what’s missing.