Skip to content

Commit e227715

Browse files
Add UI5 MCP Server and group SAP servers (#102)
- Add UI5 MCP Server (closes #77) - Group SAP servers (CAP, Fiori, MDK, UI5) in index.json - Update SAP server descriptions to be concise - Update README generator to support grouped servers with accordions
1 parent 9e80f20 commit e227715

File tree

11 files changed

+232
-56
lines changed

11 files changed

+232
-56
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ To add a server, see the [Contributing Guidelines](CONTRIBUTING.md).
2020
| **Heroku** | Manage Heroku apps and resources. | <a href="https://cursor.com/en/install-mcp?name=heroku&config=eyJjb21tYW5kIjoibnB4IC15IEBoZXJva3UvbWNwLXNlcnZlciIsImVudiI6eyJIRVJPS1VfQVBJX0tFWSI6IiJ9fQ%3D%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a> |
2121
| **Postman** | API collaboration and testing. | <a href="https://cursor.com/en/install-mcp?name=postman&config=eyJ1cmwiOiJodHRwczovL21jcC5wb3N0bWFuLmNvbS9taW5pbWFsIiwiaGVhZGVycyI6eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIFlPVVJfQVBJX0tFWSJ9fQ%3D%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a> |
2222
| **Prisma** | Manage Prisma Postgres databases, including creating new instances and running schema migrations. | <a href="https://cursor.com/en/install-mcp?name=prisma&config=eyJ1cmwiOiJodHRwczovL21jcC5wcmlzbWEuaW8vbWNwIn0%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a> |
23+
| **SAP** | <details><summary>4 servers</summary><br>- **CAP** - SAP Cloud Application Programming Model development. <a href="https://cursor.com/en/install-mcp?name=cap&config=eyJjb21tYW5kIjoibnB4IC15IEBjYXAtanMvbWNwLXNlcnZlciIsImVudiI6e319" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a><br>- **SAP Fiori** - SAP Fiori UI elements and application development. <a href="https://cursor.com/en/install-mcp?name=fiori&config=eyJjb21tYW5kIjoibnB4IC0teWVzIEBzYXAtdXgvZmlvcmktbWNwLXNlcnZlckBsYXRlc3QgZmlvcmktbWNwIiwiZW52Ijp7fX0%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a><br>- **SAP Mobile Development Kit** - SAP Mobile Development Kit tools and templates. <a href="https://cursor.com/en/install-mcp?name=mdk&config=eyJjb21tYW5kIjoibnB4IC15IEBzYXAvbWRrLW1jcC1zZXJ2ZXIiLCJlbnYiOnt9fQ%3D%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a><br>- **UI5 MCP Server** - OpenUI5 and SAPUI5 web application development. <a href="https://cursor.com/en/install-mcp?name=ui5&config=eyJjb21tYW5kIjoibnB4IC15IEB1aTUvbWNwLXNlcnZlckBsYXRlc3QifQ%3D%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a></details> | - |
2324
| **MongoDB** | Manage MongoDB data and deployments. | <a href="https://cursor.com/en/install-mcp?name=mongodb&config=eyJjb21tYW5kIjoibnB4IC15IG1vbmdvZGItbWNwLXNlcnZlciJ9" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a> |
24-
| **SAP Mobile Development Kit** | MCP server for SAP Mobile Development Kit with MDK knowledge and CLI tools. | <a href="https://cursor.com/en/install-mcp?name=mdk&config=eyJjb21tYW5kIjoibnB4IC15IEBzYXAvbWRrLW1jcC1zZXJ2ZXIiLCJlbnYiOnt9fQ%3D%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a> |
2525
| **dbt Labs** | dbt CLI, Semantic Layer, and Discovery API. | <a href="https://cursor.com/en/install-mcp?name=dbt-labs&config=eyJjb21tYW5kIjoidXZ4IGRidC1tY3AiLCJlbnYiOnsiREJUX01DUF9IT1NUIjoiY2xvdWQuZ2V0ZGJ0LmNvbSIsIk1VTFRJQ0VMTF9BQ0NPVU5UX1BSRUZJWCI6Im9wdGlvbmFsLWFjY291bnQtcHJlZml4IiwiREJUX1RPS0VOIjoieW91ci1zZXJ2aWNlLXRva2VuIiwiREJUX1BST0RfRU5WX0lEIjoieW91ci1wcm9kdWN0aW9uLWVudmlyb25tZW50LWlkIiwiREJUX0RFVl9FTlZfSUQiOiJ5b3VyLWRldmVsb3BtZW50LWVudmlyb25tZW50LWlkIiwiREJUX1VTRVJfSUQiOiJ5b3VyLXVzZXItaWQiLCJEQlRfUFJPSkVDVF9ESVIiOiIvcGF0aC90by95b3VyL2RidC9wcm9qZWN0IiwiREJUX1BBVEgiOiIvcGF0aC90by95b3VyL2RidC9leGVjdXRhYmxlIiwiRElTQUJMRV9EQlRfQ0xJIjoiZmFsc2UiLCJESVNBQkxFX1NFTUFOVElDX0xBWUVSIjoiZmFsc2UiLCJESVNBQkxFX0RJU0NPVkVSWSI6ImZhbHNlIiwiRElTQUJMRV9SRU1PVEUiOiJmYWxzZSJ9fQ%3D%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a> |
2626
| **Atlassian** | Project management and collaboration tools including Jira and Confluence. | <a href="https://cursor.com/en/install-mcp?name=atlassian&config=eyJjb21tYW5kIjoibnB4IG1jcC1yZW1vdGUgaHR0cHM6Ly9tY3AuYXRsYXNzaWFuLmNvbS92MS9zc2UifQ%3D%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a> |
2727
| **DuckDB** | In-process SQL OLAP database for local analytics. | <a href="https://cursor.com/en/install-mcp?name=duckdb&config=eyJjb21tYW5kIjoidXZ4IG1jcC1zZXJ2ZXItbW90aGVyZHVjayAtLWRiLXBhdGggOm1lbW9yeToiLCJlbnYiOnsibW90aGVyZHVja190b2tlbiI6IiJ9fQ%3D%3D" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a> |

scripts/update-readme.ts

Lines changed: 79 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ interface ServerInfo {
2525
installLink: string;
2626
}
2727

28+
interface ServerGroup {
29+
name: string;
30+
servers: ServerInfo[];
31+
}
32+
33+
type IndexEntry = string | [string, string[]];
34+
2835
function generateInstallLink(
2936
serverId: string,
3037
serverConfig: ServerConfig
@@ -69,36 +76,37 @@ function generateInstallLink(
6976
}
7077
}
7178

79+
async function loadServerInfo(
80+
serverId: string,
81+
serversDir: string
82+
): Promise<ServerInfo | null> {
83+
try {
84+
const serverConfigPath = path.join(serversDir, serverId, "server.json");
85+
const serverConfigFile = file(serverConfigPath);
86+
const serverConfig: ServerConfig = JSON.parse(
87+
await serverConfigFile.text()
88+
);
89+
90+
return {
91+
id: serverId,
92+
name: serverConfig.name,
93+
description: serverConfig.description,
94+
installLink: generateInstallLink(serverId, serverConfig),
95+
};
96+
} catch (error) {
97+
console.warn(`Failed to read config for ${serverId}:`, error);
98+
return null;
99+
}
100+
}
101+
72102
async function generateReadme(): Promise<void> {
73103
const rootDir = path.resolve(import.meta.dir, "..");
74104
const serversDir = path.join(rootDir, "servers");
75105

76-
// Read the index.json to get the ordered list of servers
106+
// Read the index.json to get the ordered list of servers and groups
77107
const indexPath = path.join(serversDir, "index.json");
78108
const indexFile = file(indexPath);
79-
const serverIds: string[] = JSON.parse(await indexFile.text());
80-
81-
// Read each server's configuration
82-
const servers: ServerInfo[] = [];
83-
84-
for (const serverId of serverIds) {
85-
try {
86-
const serverConfigPath = path.join(serversDir, serverId, "server.json");
87-
const serverConfigFile = file(serverConfigPath);
88-
const serverConfig: ServerConfig = JSON.parse(
89-
await serverConfigFile.text()
90-
);
91-
92-
servers.push({
93-
id: serverId,
94-
name: serverConfig.name,
95-
description: serverConfig.description,
96-
installLink: generateInstallLink(serverId, serverConfig),
97-
});
98-
} catch (error) {
99-
console.warn(`Failed to read config for ${serverId}:`, error);
100-
}
101-
}
109+
const indexEntries: IndexEntry[] = JSON.parse(await indexFile.text());
102110

103111
// Generate the README content
104112
let readmeContent = `# MCP Servers
@@ -111,13 +119,52 @@ To add a server, see the [Contributing Guidelines](CONTRIBUTING.md).
111119
|--------|-------------|---------|
112120
`;
113121

114-
// Add each server to the table
115-
for (const server of servers) {
116-
const installButton = server.installLink
117-
? `<a href="${server.installLink}" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a>`
118-
: "";
122+
let standaloneCount = 0;
123+
let groupCount = 0;
124+
125+
// Process each entry in order and render inline
126+
for (const entry of indexEntries) {
127+
if (typeof entry === "string") {
128+
// Standalone server
129+
const serverInfo = await loadServerInfo(entry, serversDir);
130+
if (serverInfo) {
131+
const installButton = serverInfo.installLink
132+
? `<a href="${serverInfo.installLink}" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a>`
133+
: "";
134+
135+
readmeContent += `| **${serverInfo.name}** | ${serverInfo.description} | ${installButton} |\n`;
136+
standaloneCount++;
137+
}
138+
} else if (Array.isArray(entry) && entry.length === 2) {
139+
// Group: [groupName, [serverId1, serverId2, ...]]
140+
const [groupName, serverIds] = entry;
141+
const groupServers: ServerInfo[] = [];
142+
143+
for (const serverId of serverIds) {
144+
const serverInfo = await loadServerInfo(serverId, serversDir);
145+
if (serverInfo) {
146+
groupServers.push(serverInfo);
147+
}
148+
}
119149

120-
readmeContent += `| **${server.name}** | ${server.description} | ${installButton} |\n`;
150+
if (groupServers.length > 0) {
151+
// Build a simple list of servers for the accordion content
152+
// Use <br> tags instead of newlines to keep everything on one line for markdown table compatibility
153+
let serverList = '';
154+
for (const server of groupServers) {
155+
const installButton = server.installLink
156+
? ` <a href="${server.installLink}" style="border: 1px solid rgba(128, 128, 128, 0.5); padding: 4px 8px; text-decoration: none; border-radius: 4px; font-size: 12px;">Install</a>`
157+
: "";
158+
serverList += `<br>- **${server.name}** - ${server.description}${installButton}`;
159+
}
160+
161+
// Render group as a table row with accordion in Description column
162+
// Keep everything on one line to avoid breaking markdown table parsing
163+
const detailsContent = `<details><summary>${groupServers.length} server${groupServers.length > 1 ? 's' : ''}</summary>${serverList}</details>`;
164+
readmeContent += `| **${groupName}** | ${detailsContent} | - |\n`;
165+
groupCount++;
166+
}
167+
}
121168
}
122169

123170
readmeContent += `
@@ -130,7 +177,8 @@ Each server has its own configuration requirements. Refer to the individual serv
130177
const readmePath = path.join(rootDir, "README.md");
131178
await Bun.write(readmePath, readmeContent);
132179

133-
console.log(`README.md updated with ${servers.length} servers`);
180+
const totalServers = standaloneCount + groupCount;
181+
console.log(`README.md updated with ${totalServers} entries (${standaloneCount} standalone servers, ${groupCount} groups)`);
134182
}
135183

136184
if (import.meta.main) {

servers/cap/icon.svg

Lines changed: 18 additions & 0 deletions
Loading

servers/cap/server.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "CAP",
3+
"description": "SAP Cloud Application Programming Model development.",
4+
"transport": [
5+
"stdio"
6+
],
7+
"icon": "./icon.svg",
8+
"config": {
9+
"command": "npx",
10+
"args": [
11+
"-y",
12+
"@cap-js/mcp-server"
13+
],
14+
"env": {}
15+
}
16+
}
17+

servers/fiori/icon.svg

Lines changed: 66 additions & 0 deletions
Loading

servers/fiori/server.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "SAP Fiori",
3+
"description": "SAP Fiori UI elements and application development.",
4+
"transport": [
5+
"stdio"
6+
],
7+
"icon": "./icon.svg",
8+
"config": {
9+
"command": "npx",
10+
"args": [
11+
"--yes",
12+
"@sap-ux/fiori-mcp-server@latest",
13+
"fiori-mcp"
14+
],
15+
"env": {}
16+
}
17+
}
18+

servers/index.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
"heroku",
1515
"postman",
1616
"prisma",
17+
["SAP", ["cap", "fiori", "mdk", "ui5"]],
1718
"mongodb",
18-
"mdk",
1919
"dbt-labs",
2020
"atlassian",
2121
"duckdb",

0 commit comments

Comments
 (0)