mcp-client-gen 0.0.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/LICENSE +21 -0
- package/README.md +120 -0
- package/dist/index.js +119 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-present Konstantin Tarkus, Kriasoft
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# MCP Client Generator
|
|
2
|
+
|
|
3
|
+
๐ Generate type-safe TypeScript clients from any MCP (Model Context Protocol) server.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import { notion, github, slack } from "./lib/mcp-client";
|
|
7
|
+
|
|
8
|
+
// Type-safe client calls with full IntelliSense
|
|
9
|
+
const page = await notion.createPage({
|
|
10
|
+
title: "Meeting Notes",
|
|
11
|
+
content: "Discussion about Q4 roadmap..."
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const issue = await github.createIssue({
|
|
15
|
+
title: "Bug: Login failure",
|
|
16
|
+
body: "Users cannot authenticate..."
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
await slack.notify({
|
|
20
|
+
channel: "#dev",
|
|
21
|
+
message: `New issue created: ${issue.url}`
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Features
|
|
26
|
+
|
|
27
|
+
โจ **Type-Safe** - Full TypeScript support with generated types
|
|
28
|
+
๐ **Multi-Provider** - Connect to multiple MCP servers simultaneously
|
|
29
|
+
๐ฏ **Tree-Shakable** - Only bundle the methods you use
|
|
30
|
+
โก **Fast** - Built with Bun for optimal performance
|
|
31
|
+
๐ ๏ธ **CLI-First** - Simple command-line interface
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install -g mcp-client-gen
|
|
37
|
+
# or use directly
|
|
38
|
+
npx mcp-client-gen
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
42
|
+
|
|
43
|
+
### 1. Configure MCP Servers
|
|
44
|
+
|
|
45
|
+
Create a `.mcp.json` file with your MCP server endpoints:
|
|
46
|
+
|
|
47
|
+
```jsonc
|
|
48
|
+
{
|
|
49
|
+
"mcpServers": {
|
|
50
|
+
"notion": {
|
|
51
|
+
"type": "http",
|
|
52
|
+
"url": "https://mcp.notion.com/mcp"
|
|
53
|
+
},
|
|
54
|
+
"github": {
|
|
55
|
+
"type": "http",
|
|
56
|
+
"url": "https://api.githubcopilot.com/mcp/"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 2. Generate Client SDK
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx mcp-client-gen ./lib/mcp-client.ts
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 3. Use the Generated Client
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { notion } from "./lib/mcp-client";
|
|
72
|
+
|
|
73
|
+
// All methods are fully typed based on the MCP server schema
|
|
74
|
+
const page = await notion.fetchPage("page-id");
|
|
75
|
+
const newPage = await notion.createPage({
|
|
76
|
+
title: "My Page",
|
|
77
|
+
content: "Page content..."
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## CLI Options
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx mcp-client-gen [options] <output-file>
|
|
85
|
+
|
|
86
|
+
Arguments:
|
|
87
|
+
output-file Path for the generated client file
|
|
88
|
+
|
|
89
|
+
Options:
|
|
90
|
+
--config <file> MCP configuration file (default: .mcp.json)
|
|
91
|
+
--help Show help information
|
|
92
|
+
|
|
93
|
+
Examples:
|
|
94
|
+
npx mcp-client-gen ./lib/mcp.ts
|
|
95
|
+
npx mcp-client-gen --config custom.json ./src/clients.ts
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Use Cases
|
|
99
|
+
|
|
100
|
+
๐ **API Integration** - Connect to multiple services with one SDK
|
|
101
|
+
๐ค **Workflow Automation** - Build cross-platform automation scripts
|
|
102
|
+
๐ **Data Synchronization** - Keep data in sync across different platforms
|
|
103
|
+
๐งช **Rapid Prototyping** - Quickly test integrations with type safety
|
|
104
|
+
|
|
105
|
+
## Development Status
|
|
106
|
+
|
|
107
|
+
> **Preview Release** - This is an early preview. The core CLI and configuration parsing works, but MCP server introspection is still in development.
|
|
108
|
+
|
|
109
|
+
**Current Status:**
|
|
110
|
+
- โ
CLI interface and configuration parsing
|
|
111
|
+
- โ
Multi-server client generation structure
|
|
112
|
+
- ๐ง MCP server schema introspection (in progress)
|
|
113
|
+
- ๐ง Real-time type generation from server capabilities
|
|
114
|
+
- ๐ Plugin system for custom transformations
|
|
115
|
+
|
|
116
|
+
**Coming Soon:**
|
|
117
|
+
- Full MCP protocol implementation
|
|
118
|
+
- Authentication handling
|
|
119
|
+
- Streaming support
|
|
120
|
+
- Error handling and retries
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// index.ts
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
function showHelp() {
|
|
8
|
+
console.log(`
|
|
9
|
+
mcp-client-gen - Generate type-safe MCP client SDK
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
npx mcp-client-gen <output-file>
|
|
13
|
+
npx mcp-client-gen --config <config-file> <output-file>
|
|
14
|
+
|
|
15
|
+
Arguments:
|
|
16
|
+
<output-file> Output file path for the generated client
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
--config <file> Path to MCP configuration file (default: .mcp.json)
|
|
20
|
+
--help Show this help message
|
|
21
|
+
|
|
22
|
+
Example:
|
|
23
|
+
npx mcp-client-gen ./lib/mcp-client.ts
|
|
24
|
+
npx mcp-client-gen --config custom.mcp.json ./lib/mcp.ts
|
|
25
|
+
`);
|
|
26
|
+
}
|
|
27
|
+
function parseArguments() {
|
|
28
|
+
try {
|
|
29
|
+
const { values, positionals } = parseArgs({
|
|
30
|
+
options: {
|
|
31
|
+
config: { type: "string" },
|
|
32
|
+
help: { type: "boolean", short: "h" }
|
|
33
|
+
},
|
|
34
|
+
allowPositionals: true
|
|
35
|
+
});
|
|
36
|
+
if (values.help) {
|
|
37
|
+
showHelp();
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (positionals.length === 0) {
|
|
41
|
+
console.error("Error: Missing output file argument");
|
|
42
|
+
showHelp();
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
output: positionals[0],
|
|
47
|
+
config: values.config
|
|
48
|
+
};
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error("Error parsing arguments:", error.message);
|
|
51
|
+
showHelp();
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function loadMCPConfig(configPath) {
|
|
56
|
+
const defaultConfigPath = resolve(process.cwd(), ".mcp.json");
|
|
57
|
+
const actualConfigPath = configPath ? resolve(process.cwd(), configPath) : defaultConfigPath;
|
|
58
|
+
if (!existsSync(actualConfigPath)) {
|
|
59
|
+
console.error(`Error: Configuration file not found: ${actualConfigPath}`);
|
|
60
|
+
console.error("Create a .mcp.json file with your MCP server configuration.");
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const configContent = readFileSync(actualConfigPath, "utf-8");
|
|
65
|
+
return JSON.parse(configContent);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error(`Error reading configuration file: ${error.message}`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function generateMCPClient(args) {
|
|
72
|
+
const config = loadMCPConfig(args.config);
|
|
73
|
+
const serverNames = Object.keys(config.mcpServers);
|
|
74
|
+
console.log(`Generating MCP client SDK from ${serverNames.length} servers...`);
|
|
75
|
+
console.log(`Servers: ${serverNames.join(", ")}`);
|
|
76
|
+
console.log("โณ Connecting to MCP servers...");
|
|
77
|
+
console.log("โณ Fetching server capabilities...");
|
|
78
|
+
console.log("โณ Generating TypeScript client...");
|
|
79
|
+
const clientExports = serverNames.map((name) => `export const ${name} = new ${capitalize(name)}Client("${config.mcpServers[name].url}");`).join(`
|
|
80
|
+
`);
|
|
81
|
+
const clientClasses = serverNames.map((name) => `
|
|
82
|
+
export class ${capitalize(name)}Client {
|
|
83
|
+
constructor(private serverUrl: string) {}
|
|
84
|
+
|
|
85
|
+
// TODO: Generated methods based on server capabilities
|
|
86
|
+
async fetchPage(id: string) {
|
|
87
|
+
// Implementation will be generated based on MCP server schema
|
|
88
|
+
throw new Error("Not implemented yet");
|
|
89
|
+
}
|
|
90
|
+
}`).join(`
|
|
91
|
+
`);
|
|
92
|
+
const clientCode = `// Generated MCP client SDK
|
|
93
|
+
// Generated from: ${Object.entries(config.mcpServers).map(([name, server]) => `${name} (${server.url})`).join(", ")}
|
|
94
|
+
|
|
95
|
+
${clientClasses}
|
|
96
|
+
|
|
97
|
+
${clientExports}
|
|
98
|
+
`;
|
|
99
|
+
console.log(`โ
Generated client saved to ${args.output}`);
|
|
100
|
+
console.log(`
|
|
101
|
+
Usage:`);
|
|
102
|
+
console.log(`import { ${serverNames[0]} } from "${args.output.replace(".ts", ".js")}";`);
|
|
103
|
+
console.log(`const result = await ${serverNames[0]}.fetchPage("123");`);
|
|
104
|
+
}
|
|
105
|
+
function capitalize(str) {
|
|
106
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
107
|
+
}
|
|
108
|
+
async function main() {
|
|
109
|
+
const args = parseArguments();
|
|
110
|
+
if (!args)
|
|
111
|
+
return;
|
|
112
|
+
try {
|
|
113
|
+
await generateMCPClient(args);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error("Error:", error.message);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mcp-client-gen",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "CLI tool that generates MCP client from an MCP server",
|
|
5
|
+
"module": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mcp-client-gen": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"mcp",
|
|
15
|
+
"client",
|
|
16
|
+
"generator",
|
|
17
|
+
"sdk",
|
|
18
|
+
"codegen",
|
|
19
|
+
"anthropic",
|
|
20
|
+
"cli",
|
|
21
|
+
"typescript",
|
|
22
|
+
"api-client",
|
|
23
|
+
"openapi",
|
|
24
|
+
"schema",
|
|
25
|
+
"tool",
|
|
26
|
+
"oauth"
|
|
27
|
+
],
|
|
28
|
+
"author": "Konstantin Tarkus <koistya@kriasoft.com>",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/kriasoft/mcp-client-gen.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/kriasoft/mcp-client-gen",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/kriasoft/mcp-client-gen/issues"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"typescript": "^5.9.2"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/bun": "latest",
|
|
43
|
+
"prettier": "^3.6.2"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "bun build index.ts --outdir dist --target node",
|
|
47
|
+
"prepublishOnly": "bun run build"
|
|
48
|
+
}
|
|
49
|
+
}
|