diff --git a/README.md b/README.md index e3451d2..a223822 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,31 @@ The tool automatically: - Infers server names from package names or URLs (e.g., `mcp.example.com` → `mcp-example-com`) - Handles OAuth authentication for remote servers +### Supermemory project support + +When installing a server hosted on `https://api.supermemory.ai/*`, you can pass a project name via `--project`. This is a convenience alias for adding the header `x-sm-project: `. + +Rules: + +- Only applies to URL installs targeting `https://api.supermemory.ai/*`. +- Values must not contain spaces. +- If you omit `--project` for these URLs, you'll be prompted. Pressing Enter uses `default`. +- The value is injected as a header alongside any `--header` flags. + +Examples: + +```bash +# Explicit project +npx install-mcp https://api.supermemory.ai/servers/my-server \ + --client cursor \ + --project myproj + +# Prompted for project (Enter defaults to "default") +npx install-mcp https://api.supermemory.ai/servers/my-server --client cursor +``` + +Warp users: the generated config will include `--header "x-sm-project: "` in the `args` array when installing Supermemory URLs. + ### Headers Support You can pass headers for authentication or other purposes using the `--header` flag: diff --git a/package.json b/package.json index 6e3ece9..c36150c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "install-mcp", - "version": "1.7.1", + "version": "1.8.0", "description": "A CLI tool to install and manage MCP servers.", "bin": { "install-mcp": "./bin/run" diff --git a/src/commands/install.ts b/src/commands/install.ts index b35e5a1..366148e 100644 --- a/src/commands/install.ts +++ b/src/commands/install.ts @@ -64,6 +64,7 @@ export interface InstallArgv { yes?: boolean header?: string[] oauth?: 'yes' | 'no' + project?: string } export const command = '$0 [target]' @@ -100,6 +101,7 @@ export function builder(yargs: Argv): Argv { description: 'Headers to pass to the server (format: "Header: value")', default: [], }) + .option('project', { type: 'string', description: 'Project for https://api.supermemory.ai/*' }) .option('oauth', { type: 'string', description: 'Whether the server uses OAuth authentication (yes/no). If not specified, you will be prompted.', @@ -154,6 +156,15 @@ function buildCommand(input: string): string { } } +function isSupermemoryUrl(input: string): boolean { + try { + const url = new URL(input) + return url.hostname === 'api.supermemory.ai' + } catch { + return false + } +} + // Run the authentication flow for remote servers before installation. async function runAuthentication(url: string): Promise { logger.info(`Running authentication for ${url}`) @@ -190,6 +201,24 @@ export async function handler(argv: ArgumentsCamelCase) { const name = argv.name || inferNameFromInput(target) const command = buildCommand(target) + // Resolve Supermemory project header when installing its URL + let projectHeader: string | undefined + if (isUrl(target) && isSupermemoryUrl(target)) { + let project = typeof argv.project === 'string' ? argv.project : undefined + if (!project || project.trim() === '') { + const input = (await logger.prompt( + 'Enter your Supermemory project (no spaces). Press Enter for "default" (you can override per LLM session).', + { type: 'text' }, + )) as string + project = (input || '').trim() || 'default' + } + if (/\s/.test(project)) { + logger.error('Project must not contain spaces. Use hyphens or underscores instead.') + return + } + projectHeader = `x-sm-project:${project}` + } + if (argv.client === 'warp') { logger.log('') logger.info('Warp requires a manual installation through their UI.') @@ -205,6 +234,9 @@ export async function handler(argv: ArgumentsCamelCase) { warpArgs.push('--header', header) } } + if (projectHeader) { + warpArgs.push('--header', projectHeader) + } } else { warpArgs = command.split(' ').slice(1) } @@ -280,6 +312,9 @@ export async function handler(argv: ArgumentsCamelCase) { args.push('--header', header) } } + if (projectHeader) { + args.push('--header', projectHeader) + } setServerConfig( config, configKey,