magicsword-mcp
OfficialREADME.md
# magicsword-mcp
A [Model Context Protocol](https://modelcontextprotocol.io) server for
[MagicSword](https://magicsword.io). Lets users running Claude Desktop,
Cursor, or any MCP-aware client manage MagicSword conversationally — list
endpoints, query alerts, triage findings, mint enrollment tokens, and
preview / commit policy changes.
The server is a thin, opinionated wrapper around the
`/api/public/v1/*` customer API exposed by the Magic Portal. It runs on
the user's machine, holds an `msk_…` API key, and speaks MCP over stdio.
> **Plan gate.** The customer API is Enterprise-only. With a pilot-tier key
> the server returns a clear "this MagicSword org needs the Enterprise plan
> to use MCP" message; nothing else works until the org is upgraded.
## Quick start
Requires **Node.js 22+**, an installed MCP client, and a MagicSword Enterprise
API key from **Magic Portal → Settings → API Keys**.
**Recommended: install and connect your client in one command.** Setup prompts
for your key privately and lets you choose Claude Desktop, Codex, Claude Code,
or Cursor:
```sh
npm install -g @magicsword-io/magicsword-mcp && magicsword-mcp configure
```
Already know your client? Run the matching one-liner:
| Client | Install and configure |
| --- | --- |
| Claude Desktop | `npm install -g @magicsword-io/magicsword-mcp && magicsword-mcp configure --client claude-desktop` |
| Cursor | `npm install -g @magicsword-io/magicsword-mcp && magicsword-mcp configure --client cursor` |
| Claude Code | `npm install -g @magicsword-io/magicsword-mcp && magicsword-mcp configure --client claude-code` |
| OpenAI Codex | `npm install -g @magicsword-io/magicsword-mcp && magicsword-mcp configure --client codex` |
Prefer your client's own registration command? After saving your key locally,
these also work without a global server install:
```sh
codex mcp add magicsword --env MAGICSWORD_BASE_URL=https://www.magicsword.io -- npx -y @magicsword-io/magicsword-mcp
claude mcp add --scope user --transport stdio magicsword --env MAGICSWORD_BASE_URL=https://www.magicsword.io -- npx -y @magicsword-io/magicsword-mcp
```
These are also a fallback when automatic registration cannot launch a client's
CLI on Windows. Desktop launch still requires Node/npx to be available to that
client; the recommended setup uses absolute paths instead.
### Install buttons: Cursor and VS Code
**First save your API key locally** (once per machine):
```sh
npm install -g @magicsword-io/magicsword-mcp && magicsword-mcp configure --client manual
```
Then click your client's button and approve its installation prompt:
[](https://cursor.com/en/install-mcp?name=magicsword&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBtYWdpY3N3b3JkLWlvL21hZ2ljc3dvcmQtbWNwIl0sImVudiI6eyJNQUdJQ1NXT1JEX0JBU0VfVVJMIjoiaHR0cHM6Ly93d3cubWFnaWNzd29yZC5pbyJ9fQ%3D%3D)
[](https://vscode.dev/redirect/mcp/install?name=magicsword&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40magicsword-io%2Fmagicsword-mcp%22%5D%2C%22env%22%3A%7B%22MAGICSWORD_BASE_URL%22%3A%22https%3A%2F%2Fwww.magicsword.io%22%7D%7D)
[](https://insiders.vscode.dev/redirect/mcp/install?name=magicsword&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40magicsword-io%2Fmagicsword-mcp%22%5D%2C%22env%22%3A%7B%22MAGICSWORD_BASE_URL%22%3A%22https%3A%2F%2Fwww.magicsword.io%22%7D%7D&quality=insiders)
These buttons register a local `npx` server pointing at production. They contain
no API key; the server reads `~/.magicsword/mcp.json`. They require `npx` on the
client's PATH. If a desktop app cannot find Node or npx, use the recommended
setup above for absolute launch paths, or copy the absolute `command` and
`args` printed by `configure --client manual` into its configuration.
### Manual JSON fallback
After saving your key above, merge this entry into Claude Desktop's
`claude_desktop_config.json` or Cursor's `~/.cursor/mcp.json`, preserving your
other servers:
```json
{
"mcpServers": {
"magicsword": {
"command": "npx",
"args": [
"-y",
"@magicsword-io/magicsword-mcp"
],
"env": {
"MAGICSWORD_BASE_URL": "https://www.magicsword.io"
}
}
}
}
```
For **VS Code / Insiders**, run **MCP: Open User Configuration** and merge this
configuration (VS Code uses `servers`, not `mcpServers`):
```json
{
"servers": {
"magicsword": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@magicsword-io/magicsword-mcp"
],
"env": {
"MAGICSWORD_BASE_URL": "https://www.magicsword.io"
}
}
}
}
```
Restart your client or start a new session, then ask it to call `whoami` and
`list_endpoints`. Both must succeed to verify authentication and read access.
The official MCP Registry identifier is
`io.github.magicsword-io/magicsword-mcp`. Client-specific details follow below.
## Configure
```sh
magicsword-mcp configure
```
Setup asks for an API key with hidden input (mint one in **Magic Portal →
Settings → API Keys**) and which client to connect: Claude Desktop, Codex,
Claude Code, Cursor, or manual configuration. It saves the key only in
`~/.magicsword/mcp.json` (mode 600). The Portal defaults to
`https://www.magicsword.io`, replacing any saved preview origin. A custom
origin requires an explicit `--base-url` option.
Setup registers the selected client at its standard user-level location,
preserves other servers and settings, and creates a private backup of existing
client configuration. It updates an existing `magicsword` entry for JSON clients
and Codex. Claude Code requires that name to be available; use its own MCP
commands to remove an old registration before retrying. Codex and Claude Code
registration require their respective CLIs to be installed.
To choose a client directly, or reuse a saved key without prompting:
```sh
magicsword-mcp configure --client codex
magicsword-mcp configure --non-interactive --client claude-desktop
magicsword-mcp configure --client cursor --client-config /path/to/mcp.json
```
The launch entry uses absolute Node and installed server paths so desktop apps
can start it without inheriting your terminal's PATH. Re-run setup if you move
your Node installation or install the package under a different Node version.
Manual setup prints a credential-free launch entry for other local stdio MCP
clients. Unattended setup without `--client` writes only the MagicSword file.
Restart the selected client or start a new session to load `magicsword` and its
21 tools. Ask it to call `whoami` and then `list_endpoints` to verify access;
discovery alone does not verify API-key scopes. Claude Desktop logs are at
`~/Library/Logs/Claude/mcp*.log` on macOS. Browser-only clients require a remote
MCP transport; this package provides a local stdio server.
If you need a per-client override instead of `~/.magicsword/mcp.json`, set
`MAGICSWORD_API_KEY` and optionally `MAGICSWORD_BASE_URL` in that MCP host's
environment. Keep API keys out of shared config snippets and screenshots.
## Tools
| Tool | What it does |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `whoami` | Returns organization, key id, and scopes. Always call first when troubleshooting. |
| `list_endpoints` | Lists endpoints with optional platform / status / hostname-glob filtering. |
| `show_endpoint` | Fetches one endpoint with OS, policy, compliance, upgrade, heartbeat, and AMSI details. |
| `list_agent_releases` | Lists available agent versions and per-platform latest releases. |
| `find_alerts` | Searches alerts by severity / ack state / since / hostname / MITRE technique. |
| `list_events` | Lists audit/block telemetry events, including last-day event review workflows. |
| `triage_alert` | Fetches one alert directly with triggering events, metadata, and file context; optionally acknowledges or dismisses it. |
| `list_policies` | Lists policies with current version + mode. |
| `show_policy` | Shows one policy by id. |
| `manage_policy_rules` | Lists rules or adds explicit / event-derived rules to a policy by id or name. Avoid explicit flat hash rules for Windows WDAC. |
| `apply_policy_to_endpoints` | Resolves endpoints and previews a policy assignment; `confirm=true` applies it after approval. |
| `flip_to_enforcing` | Two-step preview/confirm flip with a server-issued one-time confirm token. Safety-critical. |
| `list_customer_intel_feeds` | Lists private intel feeds or feed items. |
| `manage_customer_intel_feed` | Creates or updates feeds; deletion requires a preview followed by `confirm=true`. |
| `manage_customer_intel_item` | Edits feed items; deletion requires a preview followed by `confirm=true`. |
| `upsert_customer_intel_items` | Adds indicators extracted from reports into a private feed. |
| `manage_policy_intel_sources` | Lists, attaches, or detaches intel feeds on a policy. |
| `upgrade_endpoints` | Previews upgrades for an endpoint selection; `confirm=true` queues them after approval. |
| `request_endpoint_checkin` | Queues an endpoint check-in command. |
| `mint_enrollment_token` | Mints a one-time agent enrollment token. |
| `agent_install_instructions` | Returns the install one-liner for macOS / Linux / Windows. No API call. |
Write tools require matching Customer API scopes in Magic Portal, such as
`alerts:write`, `policies:write`, `endpoints:write`, or `intel:write`.
Event review uses `alerts:read`; turning selected events into policy rules
uses `policies:write`.
Tools publish standard MCP safety annotations. Read-only discovery tools are
marked read-only and idempotent; enforcement, deletion, policy assignment,
rule changes, and agent upgrades are marked destructive so MCP clients can
apply appropriate confirmation UX.
## Example transcript
```
User: Show me unack'd critical alerts from the last 24h.
Claude: [calls find_alerts severity=critical acknowledged=false since=...]
→ 3 critical alerts on 2 endpoints. Want me to triage the top one?
User: Yes.
Claude: [calls triage_alert]
→ Evidence chain: cmd.exe spawned by winword.exe with -enc base64.
MITRE T1059.001. Acknowledge with comment "office macro chain — under investigation"?
User: Yes, and extract the IOCs from this report into our SOC feed.
Claude: [calls upsert_customer_intel_items]
→ Upserted 47 indicators into feed 8d6...
User: Show me audited or blocked events from the last day.
Claude: [calls list_events hours=24 status=audited,blocked]
→ 31 events. Here are the file paths, publishers, and hashes.
User: Allow the first 5 on the Workstations policy.
Claude: [calls manage_policy_rules action=add policy_name=Workstations event_ids=[...] status=allowed]
→ Created a new policy version with 5 allowed rules.
```
## Configuration sources, in order of precedence
1. `MAGICSWORD_API_KEY` / `MAGICSWORD_BASE_URL` env vars (set by the MCP host).
2. `~/.magicsword/mcp.json` (or `$MAGICSWORD_CONFIG`).
3. Default base URL `https://www.magicsword.io`.
Optional transport controls are `MAGICSWORD_REQUEST_TIMEOUT_MS` (default
30 seconds), `MAGICSWORD_RESPONSE_MAX_BYTES` (default 4 MiB), and
`MAGICSWORD_GET_RETRIES` (default 2, maximum 3). Only idempotent GET requests
are retried; write actions are never retried automatically.
## Safety notes
- **`flip_to_enforcing` is two-step.** The first call returns a server preview
and one-time confirmation token; you must show the preview to a human and
pass the token back to commit. Tokens are short-lived and single-use.
- **Fleet changes and deletion are explicit.** Endpoint upgrades, policy
assignments, and private-intel deletion return a no-op preview unless the
approved follow-up call includes `confirm=true`.
- **Windows WDAC policy edits should not use explicit flat file hashes.**
Use `manage_policy_rules` with `event_ids` when approving audit events so
the Portal can derive supported path / publisher / filename rules, or use
`upsert_customer_intel_items` for hash, AuthentiHash, page-hash, and TBS
intelligence in a private feed.
- **Secrets stay on the user's machine.** The MCP server is a local stdio
process; the API key is read from `~/.magicsword/mcp.json` (mode 600) or
an env var passed by the MCP host. Nothing is sent off-machine except
the requests to the configured `MAGICSWORD_BASE_URL`.
- **Remote Portal URLs must use HTTPS.** Plain HTTP is accepted only for
localhost development. Configured URLs cannot contain credentials, paths,
query strings, or fragments.
## Develop
```sh
npm install
npm run build
npm test
npm run test:package
npm run release:verify
node dist/index.js --version
```
Tests validate `--help`, `--version`, production-default migration, private client
registration, preservation and rollback, configure validation, secret redaction,
modern and legacy MCP startup, focused mutation confirmation, retry and timeout
semantics, response-size bounds, malformed responses, write non-retry behavior,
and npm pack contents. `test:package` installs a production-only tarball and
checks the installed CLI and MCP tool discovery; `release:verify` checks all
release metadata. See `docs/RELEASING.md` for npm and MCP Registry releases.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues