ping-mcp-server 0.1.0
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/dist/index.d.ts +1 -0
- package/dist/index.js +1534 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +206 -0
- package/package.json +28 -0
- package/src/index.ts +2123 -0
- package/src/init.ts +300 -0
- package/tsconfig.json +8 -0
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/init.ts
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import * as os from "os";
|
|
7
|
+
import * as readline from "readline";
|
|
8
|
+
var API_BASE_URL = process.env.PING_API_URL || "https://api.ping-money.com";
|
|
9
|
+
var CONFIG_DIR = path.join(os.homedir(), ".ping");
|
|
10
|
+
var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
11
|
+
var CLAUDE_CONFIG_PATHS = [
|
|
12
|
+
path.join(os.homedir(), ".config", "claude-code", "config.json"),
|
|
13
|
+
path.join(os.homedir(), ".claude", "config.json"),
|
|
14
|
+
path.join(os.homedir(), "Library", "Application Support", "Claude", "config.json"),
|
|
15
|
+
path.join(os.homedir(), ".config", "claude", "config.json")
|
|
16
|
+
];
|
|
17
|
+
var BANNER = `
|
|
18
|
+
+------------------------------------------+
|
|
19
|
+
| |
|
|
20
|
+
| ____ _ |
|
|
21
|
+
| | _ \\(_)_ __ __ _ |
|
|
22
|
+
| | |_) | | '_ \\ / _\` | |
|
|
23
|
+
| | __/| | | | | (_| | |
|
|
24
|
+
| |_| |_|_| |_|\\__, | |
|
|
25
|
+
| |___/ |
|
|
26
|
+
| |
|
|
27
|
+
| Answer questions. Earn crypto. |
|
|
28
|
+
| |
|
|
29
|
+
+------------------------------------------+
|
|
30
|
+
`;
|
|
31
|
+
function print(message) {
|
|
32
|
+
console.log(message);
|
|
33
|
+
}
|
|
34
|
+
function printSuccess(message) {
|
|
35
|
+
console.log(`[OK] ${message}`);
|
|
36
|
+
}
|
|
37
|
+
function printError(message) {
|
|
38
|
+
console.log(`[ERROR] ${message}`);
|
|
39
|
+
}
|
|
40
|
+
function printInfo(message) {
|
|
41
|
+
console.log(`[INFO] ${message}`);
|
|
42
|
+
}
|
|
43
|
+
async function prompt(question) {
|
|
44
|
+
const rl = readline.createInterface({
|
|
45
|
+
input: process.stdin,
|
|
46
|
+
output: process.stdout
|
|
47
|
+
});
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
rl.question(question, (answer) => {
|
|
50
|
+
rl.close();
|
|
51
|
+
resolve(answer.trim().toLowerCase());
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function checkApiConnectivity() {
|
|
56
|
+
try {
|
|
57
|
+
const response = await fetch(`${API_BASE_URL}/health`);
|
|
58
|
+
return response.ok;
|
|
59
|
+
} catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function createConfigDirectory() {
|
|
64
|
+
try {
|
|
65
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
66
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
67
|
+
printSuccess(`Created config directory: ${CONFIG_DIR}`);
|
|
68
|
+
} else {
|
|
69
|
+
printInfo(`Config directory already exists: ${CONFIG_DIR}`);
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
printError(`Failed to create config directory: ${error}`);
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function initializeConfig() {
|
|
78
|
+
try {
|
|
79
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
80
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify({}, null, 2));
|
|
81
|
+
printSuccess(`Created config file: ${CONFIG_FILE}`);
|
|
82
|
+
} else {
|
|
83
|
+
printInfo(`Config file already exists: ${CONFIG_FILE}`);
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
printError(`Failed to create config file: ${error}`);
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function findClaudeCodeConfig() {
|
|
92
|
+
for (const configPath of CLAUDE_CONFIG_PATHS) {
|
|
93
|
+
if (fs.existsSync(configPath)) {
|
|
94
|
+
return configPath;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
function findClaudeCodeConfigDir() {
|
|
100
|
+
const existingConfig = findClaudeCodeConfig();
|
|
101
|
+
if (existingConfig) {
|
|
102
|
+
return path.dirname(existingConfig);
|
|
103
|
+
}
|
|
104
|
+
const defaultDir = path.join(os.homedir(), ".config", "claude-code");
|
|
105
|
+
return defaultDir;
|
|
106
|
+
}
|
|
107
|
+
function addToClaudeCodeConfig(configPath) {
|
|
108
|
+
try {
|
|
109
|
+
const configDir = path.dirname(configPath);
|
|
110
|
+
if (!fs.existsSync(configDir)) {
|
|
111
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
112
|
+
}
|
|
113
|
+
let config = {};
|
|
114
|
+
if (fs.existsSync(configPath)) {
|
|
115
|
+
const content = fs.readFileSync(configPath, "utf-8");
|
|
116
|
+
config = JSON.parse(content);
|
|
117
|
+
}
|
|
118
|
+
if (!config.mcpServers) {
|
|
119
|
+
config.mcpServers = {};
|
|
120
|
+
}
|
|
121
|
+
if (config.mcpServers.ping) {
|
|
122
|
+
printInfo("Ping MCP server is already configured in Claude Code");
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
config.mcpServers.ping = {
|
|
126
|
+
command: "npx",
|
|
127
|
+
args: ["-y", "@ping/mcp-server"]
|
|
128
|
+
};
|
|
129
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
130
|
+
printSuccess(`Added Ping MCP server to: ${configPath}`);
|
|
131
|
+
return true;
|
|
132
|
+
} catch (error) {
|
|
133
|
+
printError(`Failed to update Claude Code config: ${error}`);
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function main() {
|
|
138
|
+
print(BANNER);
|
|
139
|
+
print("Welcome to Ping! Let's get you set up.\n");
|
|
140
|
+
print("Checking API connectivity...");
|
|
141
|
+
const apiOk = await checkApiConnectivity();
|
|
142
|
+
if (apiOk) {
|
|
143
|
+
printSuccess(`Connected to ${API_BASE_URL}`);
|
|
144
|
+
} else {
|
|
145
|
+
printError(`Could not reach ${API_BASE_URL}`);
|
|
146
|
+
printInfo("The API may be temporarily unavailable. You can continue setup.");
|
|
147
|
+
}
|
|
148
|
+
print("");
|
|
149
|
+
print("Setting up local configuration...");
|
|
150
|
+
const dirOk = createConfigDirectory();
|
|
151
|
+
if (!dirOk) {
|
|
152
|
+
printError("Setup failed. Please check permissions and try again.");
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
const configOk = initializeConfig();
|
|
156
|
+
if (!configOk) {
|
|
157
|
+
printError("Setup failed. Please check permissions and try again.");
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
print("");
|
|
161
|
+
print("Looking for Claude Code configuration...");
|
|
162
|
+
const claudeConfigPath = findClaudeCodeConfig();
|
|
163
|
+
const claudeConfigDir = findClaudeCodeConfigDir();
|
|
164
|
+
if (claudeConfigPath) {
|
|
165
|
+
printInfo(`Found Claude Code config: ${claudeConfigPath}`);
|
|
166
|
+
} else if (claudeConfigDir) {
|
|
167
|
+
printInfo(`Will create Claude Code config at: ${path.join(claudeConfigDir, "config.json")}`);
|
|
168
|
+
}
|
|
169
|
+
const targetConfigPath = claudeConfigPath || path.join(claudeConfigDir, "config.json");
|
|
170
|
+
print("");
|
|
171
|
+
const answer = await prompt("Add Ping MCP server to Claude Code? (y/n): ");
|
|
172
|
+
if (answer === "y" || answer === "yes") {
|
|
173
|
+
const added = addToClaudeCodeConfig(targetConfigPath);
|
|
174
|
+
if (!added) {
|
|
175
|
+
printInfo("You can manually add Ping to your Claude Code config later.");
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
printInfo("Skipped Claude Code integration.");
|
|
179
|
+
printInfo("You can manually add this to your Claude Code config:");
|
|
180
|
+
print("");
|
|
181
|
+
print(" {");
|
|
182
|
+
print(' "mcpServers": {');
|
|
183
|
+
print(' "ping": {');
|
|
184
|
+
print(' "command": "npx",');
|
|
185
|
+
print(' "args": ["-y", "@ping/mcp-server"]');
|
|
186
|
+
print(" }");
|
|
187
|
+
print(" }");
|
|
188
|
+
print(" }");
|
|
189
|
+
}
|
|
190
|
+
print("");
|
|
191
|
+
print("+------------------------------------------+");
|
|
192
|
+
print("| |");
|
|
193
|
+
print("| Setup complete! |");
|
|
194
|
+
print("| |");
|
|
195
|
+
print("| Next steps: |");
|
|
196
|
+
print("| 1. Restart Claude Code |");
|
|
197
|
+
print('| 2. Say "ping_login" to connect GitHub |');
|
|
198
|
+
print("| 3. Start earning! |");
|
|
199
|
+
print("| |");
|
|
200
|
+
print("+------------------------------------------+");
|
|
201
|
+
print("");
|
|
202
|
+
}
|
|
203
|
+
main().catch((error) => {
|
|
204
|
+
printError(`Unexpected error: ${error}`);
|
|
205
|
+
process.exit(1);
|
|
206
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ping-mcp-server",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server that gives Claude Code the ability to interact with Ping",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ping-mcp": "./dist/index.js",
|
|
8
|
+
"ping-init": "./dist/init.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "tsx watch src/index.ts",
|
|
12
|
+
"build": "tsup src/index.ts src/init.ts --format esm --dts",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"test": "vitest",
|
|
15
|
+
"lint": "eslint src/",
|
|
16
|
+
"clean": "rm -rf dist"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
20
|
+
"zod": "^3.22.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^25.0.3",
|
|
24
|
+
"tsup": "^8.0.0",
|
|
25
|
+
"tsx": "^4.0.0",
|
|
26
|
+
"vitest": "^1.0.0"
|
|
27
|
+
}
|
|
28
|
+
}
|