create-glosc 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,6 +21,9 @@ Main File Name: main.py / index.ts
21
21
  Readme: Y / N
22
22
  License: MIT
23
23
  ```
24
+ 生成的项目模板现在默认是 **MCP (Model Context Protocol) stdio server**,并内置一个最基础的工具:
25
+
26
+ - `get_current_time`:返回当前 UTC 时间(ISO 8601 字符串)
24
27
 
25
28
 
26
29
  ### Python结构
@@ -29,9 +32,9 @@ License: MIT
29
32
 
30
33
  <your-project-name>/
31
34
  ├── src/ # 源代码目录
32
- │ ├── main.py # 主程序文件 (Python)
33
- ├── pyproject.toml # 项目配置
34
- │ └── requirements.txt # 依赖文件
35
+ │ ├── main.py # MCP Server 入口 (Python, stdio)
36
+ ├── pyproject.toml # 项目配置
37
+ ├── requirements.txt # 依赖文件
35
38
  ├── config.yml # 配置文件
36
39
  ├── README.md # 项目说明文件
37
40
  └── LICENSE # 许可证文件
@@ -43,13 +46,30 @@ License: MIT
43
46
  ```sh
44
47
  <your-project-name>/
45
48
  ├── src/ # 源代码目录
46
- │ ├── index.ts # 主程序文件 (TypeScript)
47
- │ └── package.json # 依赖文件
49
+ │ ├── index.ts # MCP Server 入口 (TypeScript, stdio)
50
+ ├── package.json # 依赖文件(含 @modelcontextprotocol/sdk)
48
51
  ├── config.yml # 配置文件
49
52
  ├── README.md # 项目说明文件
50
53
  └── LICENSE # 许可证文件
51
54
  ```
52
55
 
56
+ ### 运行生成的 MCP Server
57
+
58
+ Python:
59
+
60
+ ```sh
61
+ python -m pip install -r requirements.txt
62
+ python src/main.py
63
+ ```
64
+
65
+ TypeScript:
66
+
67
+ ```sh
68
+ npm install
69
+ npm run build
70
+ npm start
71
+ ```
72
+
53
73
  ### 本地开发(维护此 CLI)
54
74
 
55
75
  ```sh
package/dist/index.js CHANGED
@@ -128,7 +128,7 @@ async function run() {
128
128
  const args = parseArgs(argv);
129
129
  if (args.defaults) {
130
130
  if (!args.projectName) {
131
- throw new Error("Project name is required (e.g. `npm create glosc-cli@latest my-app -- --defaults`)");
131
+ throw new Error("Project name is required (e.g. `npm create glosc@latest my-app -- --defaults`)");
132
132
  }
133
133
  const language = normalizeLanguage(args.language) || "typescript";
134
134
  const options = {
package/dist/templates.js CHANGED
@@ -14,7 +14,11 @@ function mitLicenseText({ author }) {
14
14
  function projectReadme(options) {
15
15
  const { projectName, description, author, language, mainFileName } = options;
16
16
  const langLabel = language === "python" ? "Python" : "TypeScript";
17
- return `# ${projectName}\n\n${description || ""}\n\n## Author\n\n${author || ""}\n\n## Language\n\n${langLabel}\n\n## Entry\n\n- src/${mainFileName}\n\n## Config\n\n- config.yml\n`;
17
+ const entry = `src/${mainFileName}`;
18
+ const runSection = language === "python"
19
+ ? `## Run (Python)\n\n\n\n1) Install deps\n\n\n\n\`\`\`sh\npython -m pip install -r requirements.txt\n\`\`\`\n\n\n\n2) Run the MCP server (stdio)\n\n\n\n\`\`\`sh\npython ${entry}\n\`\`\`\n\n\n\nThis server speaks MCP over stdio. Connect using an MCP client (e.g. an editor integration).\n`
20
+ : `## Run (TypeScript)\n\n\n\n1) Install deps\n\n\n\n\`\`\`sh\nnpm install\n\`\`\`\n\n\n\n2) Build\n\n\n\n\`\`\`sh\nnpm run build\n\`\`\`\n\n\n\n3) Run the MCP server (stdio)\n\n\n\n\`\`\`sh\nnpm start\n\`\`\`\n\n\n\nThis server speaks MCP over stdio. Connect using an MCP client (e.g. an editor integration).\n`;
21
+ return `# ${projectName}\n\n${description || ""}\n\n## Author\n\n${author || ""}\n\n## Language\n\n${langLabel}\n\n## Entry\n\n- ${entry}\n\n## MCP Tools\n\n- get_current_time: Returns the current time (UTC, ISO 8601)\n\n${runSection}\n\n## Config\n\n- config.yml\n`;
18
22
  }
19
23
  function configYml(options) {
20
24
  const { projectName, description, author, language, mainFileName } = options;
@@ -27,36 +31,43 @@ function configYml(options) {
27
31
  "",
28
32
  ].join("\n");
29
33
  }
30
- function pythonMain({ projectName, description, }) {
31
- const safeName = String(projectName).replace(/"/g, '\\"');
32
- const safeDesc = String(description || "").replace(/"/g, '\\"');
33
- return `def main():\n print("${safeName}")\n ${description ? `print("${safeDesc}")` : "pass"}\n\n\nif __name__ == "__main__":\n main()\n`;
34
+ function pythonMain({ projectName, }) {
35
+ const safeName = String(projectName || "mcp-server").replace(/"/g, '\\"');
36
+ return `from datetime import datetime, timezone\n\nfrom mcp.server.fastmcp import FastMCP\n\n# Minimal MCP server (stdio)\n\nmcp = FastMCP("${safeName}")\n\n\n@mcp.tool()\nasync def get_current_time() -> str:\n """Return the current time in UTC (ISO 8601)."""\n\n return datetime.now(timezone.utc).isoformat()\n\n\ndef main():\n mcp.run(transport="stdio")\n\n\nif __name__ == "__main__":\n main()\n`;
34
37
  }
35
38
  function pythonRequirements() {
36
- return `# Add your Python dependencies here\n`;
39
+ return `mcp\n`;
37
40
  }
38
41
  function pythonPyproject({ projectName, author, }) {
39
42
  const safeName = String(projectName || "glosc-project")
40
43
  .trim()
41
44
  .replace(/\s+/g, "-");
42
45
  const safeAuthor = String(author || "").replace(/"/g, '\\"');
43
- return `# Minimal pyproject.toml (adjust as needed)\n\n[project]\nname = "${safeName}"\nversion = "0.1.0"\ndescription = ""\nauthors = [{ name = "${safeAuthor}" }]\nrequires-python = ">=3.10"\n\n[build-system]\nrequires = ["setuptools>=61.0"]\nbuild-backend = "setuptools.build_meta"\n`;
46
+ const authorsLine = safeAuthor.trim()
47
+ ? `authors = [{ name = "${safeAuthor}" }]\n`
48
+ : "";
49
+ return `# Minimal pyproject.toml (adjust as needed)\n\n[project]\nname = "${safeName}"\nversion = "0.1.0"\ndescription = ""\n${authorsLine}requires-python = ">=3.10"\ndependencies = [\n "mcp",\n]\n\n[build-system]\nrequires = ["setuptools>=61.0"]\nbuild-backend = "setuptools.build_meta"\n`;
44
50
  }
45
51
  function nodePackageJson(options) {
46
52
  const { projectName, description, author, mainFileName } = options;
47
- const main = mainFileName.replace(/\.ts$/i, ".js");
53
+ const distEntry = `dist/${mainFileName.replace(/\.ts$/i, ".js")}`;
48
54
  const pkg = {
49
55
  name: projectName,
50
56
  version: "0.1.0",
51
57
  description: description || "",
52
58
  author: author || "",
53
59
  private: true,
60
+ type: "module",
54
61
  scripts: {
55
62
  build: "tsc -p .",
56
- start: `node ${main}`,
63
+ start: `node ${distEntry}`,
64
+ },
65
+ dependencies: {
66
+ "@modelcontextprotocol/sdk": "^1.24.3",
57
67
  },
58
68
  devDependencies: {
59
- typescript: "^5.3.3",
69
+ typescript: "^5.9.3",
70
+ "@types/node": "^22.19.2",
60
71
  },
61
72
  };
62
73
  return JSON.stringify(pkg, null, 2) + "\n";
@@ -64,20 +75,23 @@ function nodePackageJson(options) {
64
75
  function tsConfig() {
65
76
  return (JSON.stringify({
66
77
  compilerOptions: {
67
- target: "ES2020",
68
- module: "CommonJS",
78
+ target: "ES2022",
79
+ module: "Node16",
69
80
  strict: true,
70
- outDir: ".",
71
- rootDir: ".",
81
+ outDir: "dist",
82
+ rootDir: "src",
72
83
  esModuleInterop: true,
84
+ moduleResolution: "Node16",
85
+ types: ["node"],
86
+ skipLibCheck: true,
87
+ forceConsistentCasingInFileNames: true,
73
88
  },
74
- include: ["*.ts"],
89
+ include: ["src/**/*.ts"],
75
90
  }, null, 2) + "\n");
76
91
  }
77
- function tsMain({ projectName, description, }) {
78
- const safeName = String(projectName).replace(/`/g, "\\`");
79
- const safeDesc = String(description || "").replace(/`/g, "\\`");
80
- return `console.log("${safeName}");\n${description ? `console.log("${safeDesc}");\n` : ""}`;
92
+ function tsMain({ projectName, }) {
93
+ const safeName = String(projectName || "mcp-server").replace(/"/g, '\\"');
94
+ return `import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";\nimport { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";\n\nconst server = new McpServer({\n name: "${safeName}",\n version: "0.1.0",\n});\n\nserver.registerTool(\n "get_current_time",\n {\n title: "Get Current Time",\n description: "Return the current time in UTC (ISO 8601)",\n inputSchema: {},\n },\n async () => {\n return {\n content: [\n {\n type: "text",\n text: new Date().toISOString(),\n },\n ],\n };\n },\n);\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error("MCP Server running on stdio");\n}\n\nmain().catch((error) => {\n console.error("Fatal error in main():", error);\n process.exit(1);\n});\n`;
81
95
  }
82
96
  function getProjectFiles(options) {
83
97
  const files = [];
@@ -100,11 +114,11 @@ function getProjectFiles(options) {
100
114
  content: pythonMain(options),
101
115
  });
102
116
  files.push({
103
- relativePath: "src/requirements.txt",
117
+ relativePath: "requirements.txt",
104
118
  content: pythonRequirements(),
105
119
  });
106
120
  files.push({
107
- relativePath: "src/pyproject.toml",
121
+ relativePath: "pyproject.toml",
108
122
  content: pythonPyproject(options),
109
123
  });
110
124
  }
@@ -114,10 +128,10 @@ function getProjectFiles(options) {
114
128
  content: tsMain(options),
115
129
  });
116
130
  files.push({
117
- relativePath: "src/package.json",
131
+ relativePath: "package.json",
118
132
  content: nodePackageJson(options),
119
133
  });
120
- files.push({ relativePath: "src/tsconfig.json", content: tsConfig() });
134
+ files.push({ relativePath: "tsconfig.json", content: tsConfig() });
121
135
  }
122
136
  return files;
123
137
  }
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "create-glosc",
3
- "version": "0.1.0",
4
- "description": "Scaffold Glosc projects (Python/TypeScript/JavaScript) via npm create",
3
+ "version": "0.1.1",
4
+ "description": "Scaffold Glosc projects (Python/TypeScript) via npm create",
5
5
  "author": "glosc-ai",
6
6
  "license": "MIT",
7
7
  "bin": {
8
+ "create-glosc": "bin/index.js",
8
9
  "glosc": "bin/index.js"
9
10
  },
10
11
  "type": "commonjs",
package/src/index.ts CHANGED
@@ -135,7 +135,7 @@ async function run(): Promise<void> {
135
135
  if (args.defaults) {
136
136
  if (!args.projectName) {
137
137
  throw new Error(
138
- "Project name is required (e.g. `npm create glosc-cli@latest my-app -- --defaults`)"
138
+ "Project name is required (e.g. `npm create glosc@latest my-app -- --defaults`)"
139
139
  );
140
140
  }
141
141
 
package/src/templates.ts CHANGED
@@ -32,9 +32,15 @@ function projectReadme(options: ProjectOptions): string {
32
32
  options;
33
33
  const langLabel = language === "python" ? "Python" : "TypeScript";
34
34
 
35
+ const entry = `src/${mainFileName}`;
36
+ const runSection =
37
+ language === "python"
38
+ ? `## Run (Python)\n\n\n\n1) Install deps\n\n\n\n\`\`\`sh\npython -m pip install -r requirements.txt\n\`\`\`\n\n\n\n2) Run the MCP server (stdio)\n\n\n\n\`\`\`sh\npython ${entry}\n\`\`\`\n\n\n\nThis server speaks MCP over stdio. Connect using an MCP client (e.g. an editor integration).\n`
39
+ : `## Run (TypeScript)\n\n\n\n1) Install deps\n\n\n\n\`\`\`sh\nnpm install\n\`\`\`\n\n\n\n2) Build\n\n\n\n\`\`\`sh\nnpm run build\n\`\`\`\n\n\n\n3) Run the MCP server (stdio)\n\n\n\n\`\`\`sh\nnpm start\n\`\`\`\n\n\n\nThis server speaks MCP over stdio. Connect using an MCP client (e.g. an editor integration).\n`;
40
+
35
41
  return `# ${projectName}\n\n${description || ""}\n\n## Author\n\n${
36
42
  author || ""
37
- }\n\n## Language\n\n${langLabel}\n\n## Entry\n\n- src/${mainFileName}\n\n## Config\n\n- config.yml\n`;
43
+ }\n\n## Language\n\n${langLabel}\n\n## Entry\n\n- ${entry}\n\n## MCP Tools\n\n- get_current_time: Returns the current time (UTC, ISO 8601)\n\n${runSection}\n\n## Config\n\n- config.yml\n`;
38
44
  }
39
45
 
40
46
  function configYml(options: ProjectOptions): string {
@@ -52,18 +58,14 @@ function configYml(options: ProjectOptions): string {
52
58
 
53
59
  function pythonMain({
54
60
  projectName,
55
- description,
56
61
  }: Pick<ProjectOptions, "projectName" | "description">): string {
57
- const safeName = String(projectName).replace(/"/g, '\\"');
58
- const safeDesc = String(description || "").replace(/"/g, '\\"');
62
+ const safeName = String(projectName || "mcp-server").replace(/"/g, '\\"');
59
63
 
60
- return `def main():\n print("${safeName}")\n ${
61
- description ? `print("${safeDesc}")` : "pass"
62
- }\n\n\nif __name__ == "__main__":\n main()\n`;
64
+ return `from datetime import datetime, timezone\n\nfrom mcp.server.fastmcp import FastMCP\n\n# Minimal MCP server (stdio)\n\nmcp = FastMCP("${safeName}")\n\n\n@mcp.tool()\nasync def get_current_time() -> str:\n """Return the current time in UTC (ISO 8601)."""\n\n return datetime.now(timezone.utc).isoformat()\n\n\ndef main():\n mcp.run(transport="stdio")\n\n\nif __name__ == "__main__":\n main()\n`;
63
65
  }
64
66
 
65
67
  function pythonRequirements(): string {
66
- return `# Add your Python dependencies here\n`;
68
+ return `mcp\n`;
67
69
  }
68
70
 
69
71
  function pythonPyproject({
@@ -76,12 +78,16 @@ function pythonPyproject({
76
78
 
77
79
  const safeAuthor = String(author || "").replace(/"/g, '\\"');
78
80
 
79
- return `# Minimal pyproject.toml (adjust as needed)\n\n[project]\nname = "${safeName}"\nversion = "0.1.0"\ndescription = ""\nauthors = [{ name = "${safeAuthor}" }]\nrequires-python = ">=3.10"\n\n[build-system]\nrequires = ["setuptools>=61.0"]\nbuild-backend = "setuptools.build_meta"\n`;
81
+ const authorsLine = safeAuthor.trim()
82
+ ? `authors = [{ name = "${safeAuthor}" }]\n`
83
+ : "";
84
+
85
+ return `# Minimal pyproject.toml (adjust as needed)\n\n[project]\nname = "${safeName}"\nversion = "0.1.0"\ndescription = ""\n${authorsLine}requires-python = ">=3.10"\ndependencies = [\n "mcp",\n]\n\n[build-system]\nrequires = ["setuptools>=61.0"]\nbuild-backend = "setuptools.build_meta"\n`;
80
86
  }
81
87
 
82
88
  function nodePackageJson(options: ProjectOptions): string {
83
89
  const { projectName, description, author, mainFileName } = options;
84
- const main = mainFileName.replace(/\.ts$/i, ".js");
90
+ const distEntry = `dist/${mainFileName.replace(/\.ts$/i, ".js")}`;
85
91
 
86
92
  const pkg: Record<string, unknown> = {
87
93
  name: projectName,
@@ -89,12 +95,17 @@ function nodePackageJson(options: ProjectOptions): string {
89
95
  description: description || "",
90
96
  author: author || "",
91
97
  private: true,
98
+ type: "module",
92
99
  scripts: {
93
100
  build: "tsc -p .",
94
- start: `node ${main}`,
101
+ start: `node ${distEntry}`,
102
+ },
103
+ dependencies: {
104
+ "@modelcontextprotocol/sdk": "^1.24.3",
95
105
  },
96
106
  devDependencies: {
97
- typescript: "^5.3.3",
107
+ typescript: "^5.9.3",
108
+ "@types/node": "^22.19.2",
98
109
  },
99
110
  };
100
111
 
@@ -106,14 +117,18 @@ function tsConfig(): string {
106
117
  JSON.stringify(
107
118
  {
108
119
  compilerOptions: {
109
- target: "ES2020",
110
- module: "CommonJS",
120
+ target: "ES2022",
121
+ module: "Node16",
111
122
  strict: true,
112
- outDir: ".",
113
- rootDir: ".",
123
+ outDir: "dist",
124
+ rootDir: "src",
114
125
  esModuleInterop: true,
126
+ moduleResolution: "Node16",
127
+ types: ["node"],
128
+ skipLibCheck: true,
129
+ forceConsistentCasingInFileNames: true,
115
130
  },
116
- include: ["*.ts"],
131
+ include: ["src/**/*.ts"],
117
132
  },
118
133
  null,
119
134
  2
@@ -123,13 +138,10 @@ function tsConfig(): string {
123
138
 
124
139
  function tsMain({
125
140
  projectName,
126
- description,
127
- }: Pick<ProjectOptions, "projectName" | "description">): string {
128
- const safeName = String(projectName).replace(/`/g, "\\`");
129
- const safeDesc = String(description || "").replace(/`/g, "\\`");
130
- return `console.log("${safeName}");\n${
131
- description ? `console.log("${safeDesc}");\n` : ""
132
- }`;
141
+ }: Pick<ProjectOptions, "projectName">): string {
142
+ const safeName = String(projectName || "mcp-server").replace(/"/g, '\\"');
143
+
144
+ return `import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";\nimport { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";\n\nconst server = new McpServer({\n name: "${safeName}",\n version: "0.1.0",\n});\n\nserver.registerTool(\n "get_current_time",\n {\n title: "Get Current Time",\n description: "Return the current time in UTC (ISO 8601)",\n inputSchema: {},\n },\n async () => {\n return {\n content: [\n {\n type: "text",\n text: new Date().toISOString(),\n },\n ],\n };\n },\n);\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error("MCP Server running on stdio");\n}\n\nmain().catch((error) => {\n console.error("Fatal error in main():", error);\n process.exit(1);\n});\n`;
133
145
  }
134
146
 
135
147
  export function getProjectFiles(options: ProjectOptions): ProjectFile[] {
@@ -157,11 +169,11 @@ export function getProjectFiles(options: ProjectOptions): ProjectFile[] {
157
169
  content: pythonMain(options),
158
170
  });
159
171
  files.push({
160
- relativePath: "src/requirements.txt",
172
+ relativePath: "requirements.txt",
161
173
  content: pythonRequirements(),
162
174
  });
163
175
  files.push({
164
- relativePath: "src/pyproject.toml",
176
+ relativePath: "pyproject.toml",
165
177
  content: pythonPyproject(options),
166
178
  });
167
179
  }
@@ -172,10 +184,10 @@ export function getProjectFiles(options: ProjectOptions): ProjectFile[] {
172
184
  content: tsMain(options),
173
185
  });
174
186
  files.push({
175
- relativePath: "src/package.json",
187
+ relativePath: "package.json",
176
188
  content: nodePackageJson(options),
177
189
  });
178
- files.push({ relativePath: "src/tsconfig.json", content: tsConfig() });
190
+ files.push({ relativePath: "tsconfig.json", content: tsConfig() });
179
191
  }
180
192
 
181
193
  return files;