Reduce instructions transferred at MCP connection to a minimum (#8649)

*  Reduce instructions transferred at MCP connection to a minimum

Force on-demand loading of the 'Penpot High-Level Overview',
which was previously transferred in the MCP server's instructions.

This greatly reduces the number of tokens for users who will
not actually interact with Penpot, allowing the MCP server to
remain enabled for such users without wasting too many tokens.

Resolves #8647

* 📎 Update Serena project
This commit is contained in:
Dr. Dominik Jain 2026-03-17 18:48:06 +01:00 committed by Dominik Jain
parent 4d3d722ecc
commit b82f67e791
5 changed files with 56 additions and 18 deletions

View File

@ -19,7 +19,7 @@ read_only: false
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
# Below is the complete list of tools for convenience.
# To make sure you have the latest list of tools, and to view their descriptions,
# To make sure you have the latest list of tools, and to view their descriptions,
# execute `uv run scripts/print_tool_overview.py`.
#
# * `activate_project`: Activates a project by name.
@ -62,15 +62,15 @@ excluded_tools: []
# (contrary to the memories, which are loaded on demand).
initial_prompt: |
IMPORTANT: You use an idiomatic, object-oriented style.
In particular, this implies that, for any non-trivial interfaces, you use interfaces that expect explicitly typed abstractions
In particular, this implies that, for any non-trivial interfaces, you use interfaces that expect explicitly typed abstractions
rather than mere functions (i.e. use the strategy pattern, for example).
Comments:
Comments:
When describing parameters, methods/functions and classes, you use a precise style, where the initial (elliptical) phrase
clearly defines *what* it is. Any details then follow in subsequent sentences.
When describing what blocks of code do, you also use an elliptical style and start with a lower-case letter unless
the comment is a lengthy explanation with at least two sentences (in which case you start with a capital letter, as is
the comment is a lengthy explanation with at least two sentences (in which case you start with a capital letter, as is
required for sentences).
# the name by which the project can be referenced within Serena
project_name: "penpot-mcp"
@ -128,3 +128,25 @@ encoding: utf-8
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
languages:
- typescript
# time budget (seconds) per tool call for the retrieval of additional symbol information
# such as docstrings or parameter information.
# This overrides the corresponding setting in the global configuration; see the documentation there.
# If null or missing, use the setting from the global configuration.
symbol_info_budget:
# The language backend to use for this project.
# If not set, the global setting from serena_config.yml is used.
# Valid values: LSP, JetBrains
# Note: the backend is fixed at startup. If a project with a different backend
# is activated post-init, an error will be returned.
language_backend:
# line ending convention to use when writing source files.
# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default)
# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings.
line_ending:
# list of regex patterns which, when matched, mark a memory entry as readonly.
# Extends the list from the global configuration, merging the two lists.
read_only_memory_patterns: []

View File

@ -0,0 +1,2 @@
You have access to Penpot tools in order to interact with Penpot designs.
Before working with these tools, be sure to read the 'Penpot High-Level Overview' via the `high_level_overview` tool.

View File

@ -4,15 +4,12 @@ import { createLogger } from "./logger.js";
/**
* Configuration loader for prompts and server settings.
*
* Handles loading and parsing of YAML configuration files,
* providing type-safe access to configuration values with
* appropriate fallbacks for missing files or values.
*/
export class ConfigurationLoader {
private readonly logger = createLogger("ConfigurationLoader");
private readonly baseDir: string;
private initialInstructions: string;
private readonly initialInstructions: string;
private readonly baseInstructions: string;
/**
* Creates a new configuration loader instance.
@ -22,6 +19,7 @@ export class ConfigurationLoader {
constructor(baseDir: string) {
this.baseDir = baseDir;
this.initialInstructions = this.loadFileContent(join(this.baseDir, "data", "initial_instructions.md"));
this.baseInstructions = this.loadFileContent(join(this.baseDir, "data", "base_instructions.md"));
}
private loadFileContent(filePath: string): string {
@ -32,11 +30,22 @@ export class ConfigurationLoader {
}
/**
* Gets the initial instructions for the MCP server.
* Gets the initial instructions for the MCP server corresponding to the
* 'Penpot High-Level Overview'
*
* @returns The initial instructions string, or undefined if not configured
* @returns The initial instructions string
*/
public getInitialInstructions(): string {
return this.initialInstructions;
}
/**
* Gets the base instructions which shall be provided to clients when connecting to
* the MCP server
*
* @returns The initial instructions string
*/
public getBaseInstructions(): string {
return this.baseInstructions;
}
}

View File

@ -56,7 +56,8 @@ export class PenpotMcpServer {
public readonly pluginBridge: PluginBridge;
private readonly replServer: ReplServer;
private apiDocs: ApiDocs;
private initialInstructions: string;
private readonly penpotHighLevelOverview: string;
private readonly connectionInstructions: string;
/**
* Manages session-specific context, particularly user tokens for each request.
@ -82,10 +83,11 @@ export class PenpotMcpServer {
this.configLoader = new ConfigurationLoader(process.cwd());
this.apiDocs = new ApiDocs();
// prepare initial instructions
// prepare instructions
let instructions = this.configLoader.getInitialInstructions();
instructions = instructions.replace("$api_types", this.apiDocs.getTypeNames().join(", "));
this.initialInstructions = instructions;
this.penpotHighLevelOverview = instructions;
this.connectionInstructions = this.configLoader.getBaseInstructions();
this.tools = this.initTools();
@ -124,8 +126,11 @@ export class PenpotMcpServer {
return !this.isRemoteMode();
}
public getInitialInstructions(): string {
return this.initialInstructions;
/**
* Retrieves the high-level overview instructions explaining core Penpot usage.
*/
public getHighLevelOverviewInstructions(): string {
return this.penpotHighLevelOverview;
}
/**
@ -163,7 +168,7 @@ export class PenpotMcpServer {
private createMcpServer(): McpServer {
const server = new McpServer(
{ name: "penpot", version: "1.0.0" },
{ instructions: this.getInitialInstructions() }
{ instructions: this.connectionInstructions }
);
for (const tool of this.tools) {

View File

@ -21,6 +21,6 @@ export class HighLevelOverviewTool extends Tool<EmptyToolArgs> {
}
protected async executeCore(args: EmptyToolArgs): Promise<ToolResponse> {
return new TextResponse(this.mcpServer.getInitialInstructions());
return new TextResponse(this.mcpServer.getHighLevelOverviewInstructions());
}
}