mcpstore-cc 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/README.md +54 -0
- package/dist/commands/install.d.ts +3 -0
- package/dist/commands/install.js +74 -0
- package/dist/commands/list.d.ts +1 -0
- package/dist/commands/list.js +31 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +23 -0
- package/dist/commands/search.d.ts +1 -0
- package/dist/commands/search.js +31 -0
- package/dist/commands/uninstall.d.ts +1 -0
- package/dist/commands/uninstall.js +21 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +53 -0
- package/dist/lib/api.d.ts +22 -0
- package/dist/lib/api.js +24 -0
- package/dist/lib/config.d.ts +17 -0
- package/dist/lib/config.js +57 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# mcpstore
|
|
2
|
+
|
|
3
|
+
CLI to install MCPs from [MCP Store](https://www.mcpclaudecode.com) into Claude Code.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx mcpstore-cc install <slug>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
No global install required — just use `npx`.
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
### Install an MCP
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx mcpstore-cc install ai-brain
|
|
19
|
+
npx mcpstore-cc install supabase-mcp --env SUPABASE_URL=https://xxx.supabase.co
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Uninstall an MCP
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx mcpstore-cc uninstall ai-brain
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### List installed MCPs
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx mcpstore-cc list
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Search available MCPs
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx mcpstore-cc search database
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Save your API key
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx mcpstore-cc login <your-api-key>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## How it works
|
|
47
|
+
|
|
48
|
+
1. Fetches MCP configuration from the MCP Store API
|
|
49
|
+
2. Adds the server entry to `~/.claude/.mcp.json`
|
|
50
|
+
3. Restart Claude Code to activate
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
MIT
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import { fetchMcp } from "../lib/api.js";
|
|
4
|
+
import { addMcpServer, listMcpServers, getMcpConfigPath } from "../lib/config.js";
|
|
5
|
+
export async function installCommand(slug, options) {
|
|
6
|
+
const spinner = ora(`Fetching "${slug}" from MCP Store...`).start();
|
|
7
|
+
try {
|
|
8
|
+
const mcp = await fetchMcp(slug);
|
|
9
|
+
spinner.succeed(`Found: ${chalk.bold(mcp.name)} v${mcp.version} by ${mcp.author_name}`);
|
|
10
|
+
// Check if already installed
|
|
11
|
+
const existing = await listMcpServers();
|
|
12
|
+
if (slug in existing) {
|
|
13
|
+
console.log(chalk.yellow(`\n⚠ "${slug}" is already installed in Claude Code.`));
|
|
14
|
+
console.log(chalk.gray(" Use `mcpstore uninstall " + slug + "` first to reinstall."));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
// Build server config from config_schema or npm_package
|
|
18
|
+
let command;
|
|
19
|
+
let args;
|
|
20
|
+
let env = {};
|
|
21
|
+
if (mcp.config_schema && mcp.config_schema.command) {
|
|
22
|
+
// Use the config_schema from the API
|
|
23
|
+
command = mcp.config_schema.command;
|
|
24
|
+
args = mcp.config_schema.args || [];
|
|
25
|
+
env = mcp.config_schema.env || {};
|
|
26
|
+
}
|
|
27
|
+
else if (mcp.npm_package) {
|
|
28
|
+
// Fallback: use npx with the npm package
|
|
29
|
+
command = "npx";
|
|
30
|
+
args = ["-y", mcp.npm_package];
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.log(chalk.red("\n✗ This MCP has no installation config. Contact the author."));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Merge env vars from --env flags
|
|
37
|
+
if (options.env) {
|
|
38
|
+
for (const pair of options.env) {
|
|
39
|
+
const eqIdx = pair.indexOf("=");
|
|
40
|
+
if (eqIdx === -1) {
|
|
41
|
+
console.log(chalk.yellow(`\n⚠ Skipping invalid env: "${pair}" (use KEY=VALUE format)`));
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const key = pair.slice(0, eqIdx);
|
|
45
|
+
const value = pair.slice(eqIdx + 1);
|
|
46
|
+
env[key] = value;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Check if config_schema defines required env vars we're missing
|
|
50
|
+
if (mcp.config_schema?.env) {
|
|
51
|
+
const schemaEnv = mcp.config_schema.env;
|
|
52
|
+
const missingKeys = Object.keys(schemaEnv).filter((k) => !env[k] && schemaEnv[k] !== "");
|
|
53
|
+
if (missingKeys.length > 0) {
|
|
54
|
+
console.log(chalk.yellow("\n⚠ This MCP requires environment variables:"));
|
|
55
|
+
for (const key of missingKeys) {
|
|
56
|
+
console.log(chalk.gray(` ${key}=${schemaEnv[key] || "<your-value>"}`));
|
|
57
|
+
}
|
|
58
|
+
console.log(chalk.gray("\n Pass them with: mcpstore install " + slug + " --env " + missingKeys.map((k) => `${k}=<value>`).join(" --env ")));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Write to ~/.claude/.mcp.json
|
|
62
|
+
const spinner2 = ora("Adding to Claude Code config...").start();
|
|
63
|
+
const entry = { command, args, ...(Object.keys(env).length > 0 ? { env } : {}) };
|
|
64
|
+
await addMcpServer(slug, entry);
|
|
65
|
+
spinner2.succeed("Added to Claude Code config");
|
|
66
|
+
console.log(chalk.green(`\n✓ ${chalk.bold(mcp.name)} installed successfully!`));
|
|
67
|
+
console.log(chalk.gray(` Config: ${getMcpConfigPath()}`));
|
|
68
|
+
console.log(chalk.gray(` Restart Claude Code to activate this MCP.\n`));
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
spinner.fail(err.message);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function listCommand(): Promise<void>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { listMcpServers, getMcpConfigPath } from "../lib/config.js";
|
|
3
|
+
export async function listCommand() {
|
|
4
|
+
try {
|
|
5
|
+
const servers = await listMcpServers();
|
|
6
|
+
const names = Object.keys(servers);
|
|
7
|
+
if (names.length === 0) {
|
|
8
|
+
console.log(chalk.gray("\nNo MCPs installed in Claude Code."));
|
|
9
|
+
console.log(chalk.gray(" Browse MCPs at https://www.mcpclaudecode.com/browse"));
|
|
10
|
+
console.log(chalk.gray(" Install one with: mcpstore install <slug>\n"));
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
console.log(chalk.bold(`\n${names.length} MCP(s) installed in Claude Code:\n`));
|
|
14
|
+
for (const name of names) {
|
|
15
|
+
const server = servers[name];
|
|
16
|
+
const cmdStr = [server.command, ...server.args].join(" ");
|
|
17
|
+
console.log(` ${chalk.green("●")} ${chalk.bold(name)}`);
|
|
18
|
+
console.log(chalk.gray(` ${cmdStr}`));
|
|
19
|
+
if (server.env && Object.keys(server.env).length > 0) {
|
|
20
|
+
const envKeys = Object.keys(server.env);
|
|
21
|
+
console.log(chalk.gray(` env: ${envKeys.join(", ")}`));
|
|
22
|
+
}
|
|
23
|
+
console.log();
|
|
24
|
+
}
|
|
25
|
+
console.log(chalk.gray(`Config: ${getMcpConfigPath()}\n`));
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error(chalk.red(err.message));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { saveApiKey, getStoredApiKey } from "../lib/config.js";
|
|
3
|
+
export async function loginCommand(apiKey) {
|
|
4
|
+
try {
|
|
5
|
+
await saveApiKey(apiKey);
|
|
6
|
+
console.log(chalk.green("\n✓ API key saved successfully!"));
|
|
7
|
+
console.log(chalk.gray(" Stored in ~/.mcpstore/config.json\n"));
|
|
8
|
+
}
|
|
9
|
+
catch (err) {
|
|
10
|
+
console.error(chalk.red(err.message));
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function whoamiCommand() {
|
|
15
|
+
const key = await getStoredApiKey();
|
|
16
|
+
if (!key) {
|
|
17
|
+
console.log(chalk.gray("\nNot logged in."));
|
|
18
|
+
console.log(chalk.gray(" Run: mcpstore login <your-api-key>\n"));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const masked = key.slice(0, 8) + "..." + key.slice(-4);
|
|
22
|
+
console.log(`\nLogged in with API key: ${chalk.bold(masked)}\n`);
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function searchCommand(query?: string): Promise<void>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import { searchMcps } from "../lib/api.js";
|
|
4
|
+
export async function searchCommand(query) {
|
|
5
|
+
const spinner = ora(query ? `Searching for "${query}"...` : "Fetching MCPs...").start();
|
|
6
|
+
try {
|
|
7
|
+
const mcps = await searchMcps(query);
|
|
8
|
+
spinner.stop();
|
|
9
|
+
if (mcps.length === 0) {
|
|
10
|
+
console.log(chalk.gray("\nNo MCPs found."));
|
|
11
|
+
if (query) {
|
|
12
|
+
console.log(chalk.gray(` Try a different search term or browse at https://www.mcpclaudecode.com/browse\n`));
|
|
13
|
+
}
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
console.log(chalk.bold(`\n${mcps.length} MCP(s) found:\n`));
|
|
17
|
+
for (const mcp of mcps) {
|
|
18
|
+
const badge = mcp.plan_required !== "free" ? chalk.yellow(` [${mcp.plan_required.toUpperCase()}]`) : "";
|
|
19
|
+
const stars = mcp.rating_avg > 0 ? chalk.yellow(` ★ ${mcp.rating_avg.toFixed(1)}`) : "";
|
|
20
|
+
const installs = mcp.install_count > 0 ? chalk.gray(` (${mcp.install_count} installs)`) : "";
|
|
21
|
+
console.log(` ${chalk.bold(mcp.name)}${badge}${stars}${installs}`);
|
|
22
|
+
console.log(chalk.gray(` ${mcp.short_description || mcp.description?.slice(0, 80) || ""}`));
|
|
23
|
+
console.log(chalk.cyan(` mcpstore install ${mcp.slug}`));
|
|
24
|
+
console.log();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
spinner.fail(err.message);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function uninstallCommand(slug: string): Promise<void>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import ora from "ora";
|
|
3
|
+
import { removeMcpServer, getMcpConfigPath } from "../lib/config.js";
|
|
4
|
+
export async function uninstallCommand(slug) {
|
|
5
|
+
const spinner = ora(`Removing "${slug}" from Claude Code...`).start();
|
|
6
|
+
try {
|
|
7
|
+
const removed = await removeMcpServer(slug);
|
|
8
|
+
if (!removed) {
|
|
9
|
+
spinner.warn(`"${slug}" is not installed in Claude Code.`);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
spinner.succeed(`Removed "${slug}" from Claude Code config`);
|
|
13
|
+
console.log(chalk.green(`\n✓ ${chalk.bold(slug)} uninstalled successfully!`));
|
|
14
|
+
console.log(chalk.gray(` Config: ${getMcpConfigPath()}`));
|
|
15
|
+
console.log(chalk.gray(` Restart Claude Code to apply changes.\n`));
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
spinner.fail(err.message);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { installCommand } from "./commands/install.js";
|
|
4
|
+
import { uninstallCommand } from "./commands/uninstall.js";
|
|
5
|
+
import { listCommand } from "./commands/list.js";
|
|
6
|
+
import { searchCommand } from "./commands/search.js";
|
|
7
|
+
import { loginCommand, whoamiCommand } from "./commands/login.js";
|
|
8
|
+
const program = new Command();
|
|
9
|
+
program
|
|
10
|
+
.name("mcpstore")
|
|
11
|
+
.description("Install MCPs from MCP Store into Claude Code")
|
|
12
|
+
.version("0.1.0");
|
|
13
|
+
program
|
|
14
|
+
.command("install <slug>")
|
|
15
|
+
.description("Install an MCP into Claude Code")
|
|
16
|
+
.option("-e, --env <KEY=VALUE...>", "Set environment variables", (val, acc) => {
|
|
17
|
+
acc.push(val);
|
|
18
|
+
return acc;
|
|
19
|
+
}, [])
|
|
20
|
+
.action(async (slug, opts) => {
|
|
21
|
+
await installCommand(slug, { env: opts.env.length > 0 ? opts.env : undefined });
|
|
22
|
+
});
|
|
23
|
+
program
|
|
24
|
+
.command("uninstall <slug>")
|
|
25
|
+
.description("Remove an MCP from Claude Code")
|
|
26
|
+
.action(async (slug) => {
|
|
27
|
+
await uninstallCommand(slug);
|
|
28
|
+
});
|
|
29
|
+
program
|
|
30
|
+
.command("list")
|
|
31
|
+
.description("List all MCPs installed in Claude Code")
|
|
32
|
+
.action(async () => {
|
|
33
|
+
await listCommand();
|
|
34
|
+
});
|
|
35
|
+
program
|
|
36
|
+
.command("search [query]")
|
|
37
|
+
.description("Search MCPs on MCP Store")
|
|
38
|
+
.action(async (query) => {
|
|
39
|
+
await searchCommand(query);
|
|
40
|
+
});
|
|
41
|
+
program
|
|
42
|
+
.command("login <api-key>")
|
|
43
|
+
.description("Save your MCP Store API key")
|
|
44
|
+
.action(async (apiKey) => {
|
|
45
|
+
await loginCommand(apiKey);
|
|
46
|
+
});
|
|
47
|
+
program
|
|
48
|
+
.command("whoami")
|
|
49
|
+
.description("Show current logged-in API key")
|
|
50
|
+
.action(async () => {
|
|
51
|
+
await whoamiCommand();
|
|
52
|
+
});
|
|
53
|
+
program.parse();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface McpConfig {
|
|
2
|
+
command: string;
|
|
3
|
+
args: string[];
|
|
4
|
+
env?: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
export interface McpDetail {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
slug: string;
|
|
10
|
+
description: string;
|
|
11
|
+
short_description: string;
|
|
12
|
+
author_name: string;
|
|
13
|
+
npm_package: string | null;
|
|
14
|
+
version: string;
|
|
15
|
+
plan_required: string;
|
|
16
|
+
install_count: number;
|
|
17
|
+
rating_avg: number;
|
|
18
|
+
rating_count: number;
|
|
19
|
+
config_schema: McpConfig | null;
|
|
20
|
+
}
|
|
21
|
+
export declare function fetchMcp(slug: string): Promise<McpDetail>;
|
|
22
|
+
export declare function searchMcps(query?: string): Promise<McpDetail[]>;
|
package/dist/lib/api.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const API_BASE = "https://aibrain-mcp-backend.vercel.app/v1";
|
|
2
|
+
export async function fetchMcp(slug) {
|
|
3
|
+
const res = await fetch(`${API_BASE}/marketplace/mcps/${slug}`);
|
|
4
|
+
if (!res.ok) {
|
|
5
|
+
if (res.status === 404) {
|
|
6
|
+
throw new Error(`MCP "${slug}" not found on MCP Store.`);
|
|
7
|
+
}
|
|
8
|
+
throw new Error(`API error: ${res.status} ${res.statusText}`);
|
|
9
|
+
}
|
|
10
|
+
const data = await res.json();
|
|
11
|
+
return data.mcp ?? data;
|
|
12
|
+
}
|
|
13
|
+
export async function searchMcps(query) {
|
|
14
|
+
const params = new URLSearchParams();
|
|
15
|
+
if (query)
|
|
16
|
+
params.set("search", query);
|
|
17
|
+
params.set("limit", "50");
|
|
18
|
+
const res = await fetch(`${API_BASE}/marketplace/mcps?${params}`);
|
|
19
|
+
if (!res.ok) {
|
|
20
|
+
throw new Error(`API error: ${res.status} ${res.statusText}`);
|
|
21
|
+
}
|
|
22
|
+
const data = await res.json();
|
|
23
|
+
return data.mcps ?? data;
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface McpServerEntry {
|
|
2
|
+
command: string;
|
|
3
|
+
args: string[];
|
|
4
|
+
env?: Record<string, string>;
|
|
5
|
+
}
|
|
6
|
+
interface McpConfigFile {
|
|
7
|
+
mcpServers: Record<string, McpServerEntry>;
|
|
8
|
+
}
|
|
9
|
+
export declare function readMcpConfig(): Promise<McpConfigFile>;
|
|
10
|
+
export declare function writeMcpConfig(config: McpConfigFile): Promise<void>;
|
|
11
|
+
export declare function addMcpServer(name: string, entry: McpServerEntry): Promise<void>;
|
|
12
|
+
export declare function removeMcpServer(name: string): Promise<boolean>;
|
|
13
|
+
export declare function listMcpServers(): Promise<Record<string, McpServerEntry>>;
|
|
14
|
+
export declare function getStoredApiKey(): Promise<string | null>;
|
|
15
|
+
export declare function saveApiKey(apiKey: string): Promise<void>;
|
|
16
|
+
export declare function getMcpConfigPath(): string;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
// ── Claude Code MCP config ──────────────────────────────────────
|
|
6
|
+
const CLAUDE_DIR = join(homedir(), ".claude");
|
|
7
|
+
const MCP_CONFIG_PATH = join(CLAUDE_DIR, ".mcp.json");
|
|
8
|
+
export async function readMcpConfig() {
|
|
9
|
+
if (!existsSync(MCP_CONFIG_PATH)) {
|
|
10
|
+
return { mcpServers: {} };
|
|
11
|
+
}
|
|
12
|
+
const raw = await readFile(MCP_CONFIG_PATH, "utf-8");
|
|
13
|
+
return JSON.parse(raw);
|
|
14
|
+
}
|
|
15
|
+
export async function writeMcpConfig(config) {
|
|
16
|
+
if (!existsSync(CLAUDE_DIR)) {
|
|
17
|
+
await mkdir(CLAUDE_DIR, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
await writeFile(MCP_CONFIG_PATH, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
20
|
+
}
|
|
21
|
+
export async function addMcpServer(name, entry) {
|
|
22
|
+
const config = await readMcpConfig();
|
|
23
|
+
config.mcpServers[name] = entry;
|
|
24
|
+
await writeMcpConfig(config);
|
|
25
|
+
}
|
|
26
|
+
export async function removeMcpServer(name) {
|
|
27
|
+
const config = await readMcpConfig();
|
|
28
|
+
if (!(name in config.mcpServers)) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
delete config.mcpServers[name];
|
|
32
|
+
await writeMcpConfig(config);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
export async function listMcpServers() {
|
|
36
|
+
const config = await readMcpConfig();
|
|
37
|
+
return config.mcpServers;
|
|
38
|
+
}
|
|
39
|
+
// ── mcpstore CLI config (API key storage) ───────────────────────
|
|
40
|
+
const MCPSTORE_DIR = join(homedir(), ".mcpstore");
|
|
41
|
+
const MCPSTORE_CONFIG = join(MCPSTORE_DIR, "config.json");
|
|
42
|
+
export async function getStoredApiKey() {
|
|
43
|
+
if (!existsSync(MCPSTORE_CONFIG))
|
|
44
|
+
return null;
|
|
45
|
+
const raw = await readFile(MCPSTORE_CONFIG, "utf-8");
|
|
46
|
+
const data = JSON.parse(raw);
|
|
47
|
+
return data.apiKey ?? null;
|
|
48
|
+
}
|
|
49
|
+
export async function saveApiKey(apiKey) {
|
|
50
|
+
if (!existsSync(MCPSTORE_DIR)) {
|
|
51
|
+
await mkdir(MCPSTORE_DIR, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
await writeFile(MCPSTORE_CONFIG, JSON.stringify({ apiKey }, null, 2) + "\n", "utf-8");
|
|
54
|
+
}
|
|
55
|
+
export function getMcpConfigPath() {
|
|
56
|
+
return MCP_CONFIG_PATH;
|
|
57
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mcpstore-cc",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI to install MCPs from MCP Store into Claude Code",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mcpstore": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsc --watch",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["mcp", "claude-code", "marketplace", "cli"],
|
|
15
|
+
"author": "MCP Store",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"commander": "^12.1.0",
|
|
19
|
+
"chalk": "^5.3.0",
|
|
20
|
+
"ora": "^8.1.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^22.0.0",
|
|
24
|
+
"typescript": "^5.6.0"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18.0.0"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
]
|
|
32
|
+
}
|