Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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: <value>`.

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: <value>"` in the `args` array when installing Supermemory URLs.

### Headers Support

You can pass headers for authentication or other purposes using the `--header` flag:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
35 changes: 35 additions & 0 deletions src/commands/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export interface InstallArgv {
yes?: boolean
header?: string[]
oauth?: 'yes' | 'no'
project?: string
}

export const command = '$0 [target]'
Expand Down Expand Up @@ -100,6 +101,7 @@ export function builder(yargs: Argv<InstallArgv>): 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.',
Expand Down Expand Up @@ -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<void> {
logger.info(`Running authentication for ${url}`)
Expand Down Expand Up @@ -190,6 +201,24 @@ export async function handler(argv: ArgumentsCamelCase<InstallArgv>) {
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.')
Expand All @@ -205,6 +234,9 @@ export async function handler(argv: ArgumentsCamelCase<InstallArgv>) {
warpArgs.push('--header', header)
}
}
if (projectHeader) {
warpArgs.push('--header', projectHeader)
}
} else {
warpArgs = command.split(' ').slice(1)
}
Expand Down Expand Up @@ -280,6 +312,9 @@ export async function handler(argv: ArgumentsCamelCase<InstallArgv>) {
args.push('--header', header)
}
}
if (projectHeader) {
args.push('--header', projectHeader)
}
setServerConfig(
config,
configKey,
Expand Down