# AINSOF (remote · mcp.ainsof.io)

Human-made production music for sync — search by brief or reference, preview, score to picture.

- Trust score: 70/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-18

> **Recent critical change**: Authorization (2026-08-10). See the changelog below before you install this server.

## Components

- remote · `mcp.ainsof.io`: 70/100 (this document), [markdown](https://verifymcp.io/servers/io-ainsof-mcp/mcp.md), [page](https://verifymcp.io/servers/io-ainsof-mcp/mcp)

## Channel facts

- Endpoint: `https://mcp.ainsof.io`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.0.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-18.

- **Endpoint Security**: 63/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation check failed: no authorisation is required to call this server, and it exposes a tool marked destructive (feedback).
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 75/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 4583 tokens (~352/item across 13 items; 12 tools + 1 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 37/100
  - Stability observed for 11 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 93/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 78% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.
  - Supports UI / widget rendering.

## Install

### Claude

```bash
claude mcp add --transport http io-ainsof-mcp https://mcp.ainsof.io/
```

### Codex

```toml
[mcp_servers.io-ainsof-mcp]
url = "https://mcp.ainsof.io/"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "io-ainsof-mcp": {
      "type": "remote",
      "url": "https://mcp.ainsof.io/",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add io-ainsof-mcp --url https://mcp.ainsof.io/ --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  io-ainsof-mcp:
    url: "https://mcp.ainsof.io/"
```

### Other

```json
{
  "mcpServers": {
    "io-ainsof-mcp": {
      "type": "http",
      "url": "https://mcp.ainsof.io/"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-18 (score 70, +1)

No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-15 (score 69, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-13 (score 68, +1)

No change was recorded against any check on this day. Stability & Change Management went from 17 to 20. That category is still filling its 30-day observation window: 5 days of observed history at the previous scan, 6 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-12 (score 67, +1)

No change was recorded against any check on this day. Stability & Change Management went from 13 to 17. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 5 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-11 (score 66, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-08-10 (score 65, −6)

- [critical regression] Authorization: partial → fail
- [security] The server rewrote its instructions, which are the text every model session reads
- [security] Tool “analyze_video” rewrote its description, which is the text the model reads
- [security] Tool “find_soundtrack” rewrote its description, which is the text the model reads
- [security] Tool “get_upload_link” rewrote its description, which is the text the model reads
- [security] Tool “score_my_video” rewrote its description, which is the text the model reads
- [security] Tool “search_by_reference” rewrote its description, which is the text the model reads
- [security] Tool “feedback” is now declared destructive
- [functional] Server version: 1.0.6 → 1.0.7

### 2026-08-08 (score 71, +2)

- [security] Tool “score_my_video” rewrote its description, which is the text the model reads
- [functional improvement] Stability: unverified → 0.03
- [functional] Server version: 1.0.5 → 1.0.6

### 2026-08-07 (score 69)

First indexed and scored.

## MCP tools (12)

### `find_soundtrack` (~171 tokens)

Find music for a video. Given the video's length and a description of it, returns three cues from the AINSOF catalogue, each already matched to the version that fits that exact duration — a 30-second cut for a 30-second video rather than a full track the editor has to trim. Every result comes with its composer, publisher and a watermarked preview to listen to. Use this when someone asks for music or a soundtrack for a video and its exact duration is available.

Input parameters:

- `cuts_per_min` (number): edit pace, if known
- `description` (string): what the video shows, in musical terms
- `duration_sec` (number, required): the video's length in seconds
- `has_narration` (boolean): true if anyone speaks over it
- `product` (string)

### `score_my_video` (~718 tokens)

Put music on a video and hand back the finished file. Give a link to the video and a brief, and this measures the video, picks the AINSOF cue that fits its exact length and edit pace, mixes it underneath any existing dialogue at a level that keeps speech clear, and returns an MP4 the user can download and watch. Accepts a direct video URL or a Dropbox or Google Drive share link; for YouTube, Vimeo, Dailymotion or Twitch we cannot pull the file, so ask for the file itself or use get_upload_link. Pass track_id instead of a brief when the user has already chosen a cue. DIRECTING THE SCORE. A user who says what they want at each moment — "big opening, then pull back when she reads the letter, then build to the last shot" — is describing `sections`, not one brief. Pass a list of {from, to, brief} and each act gets its own cue chosen from its own words; add track_id, version or stems to an act to pin it exactly. Use `silences` for the opposite move — a moment the music stops dead. Both are snapped onto the video's real shot boundaries, so a boundary lands ON the cut. Call analyze_video first if you need the cut list to place them. To revise a score, call again with the same arguments and change only what the user asked to change — the response tells you how. Rendering takes about a minute, so the first reply is often { ok: false, error: "still_running" } — that is normal and not a failure. Call it AGAIN with the same arguments; it picks up the render already in progress rather than starting a second one. A genuine failure comes back as error "video_failed" with a reason to pass on.

Input parameters:

- `brief` (string): the music you want, IN ENGLISH
- `music_offset_db` (number): how far under the video's own audio the music sits, in dB. Negative is quieter; 0 is level with it. Leave unset for the default.
- `sections` (array): DIFFERENT MUSIC FOR DIFFERENT PARTS OF THE STORY. Use this when a brief asks for acts, distinct sections, a change of character, or a separate cue for a specific sequence. Each section gets its own c…
- `silences` (array): MOMENTS WHERE THE MUSIC STOPS DEAD. Briefs ask for this in as many words — "drop the music out completely when the statue is destroyed" — and it is the single most effective thing a score does. Each…
- `track_id` (string): use this exact cue instead, e.g. 'AIN-CAT 006_004'
- `version` (string): force a version — MAIN, CUT_30, CUT_60…
- `video_url` (string, required): link to the video

### `deliver_score` (~188 tokens)

Hand over the finished score as files, once the user is happy with it. Returns a zip holding the scored video, every section of music as a separate WAV trimmed exactly as it was used and named with the timecode it starts at, and a cue sheet. An editor drops each file at the timecode in its name and has the render back on their own timeline. Call this with THE SAME arguments you passed to score_my_video — that is how it finds the right render. It never re-cuts anything.

Input parameters:

- `brief` (string): the same brief you scored with
- `music_offset_db` (number): the same value you scored with, if you set one
- `sections` (array)
- `silences` (array)
- `track_id` (string)
- `version` (string)
- `video_url` (string, required): the same link you scored

### `get_upload_link` (~226 tokens)

Use this when the user says their video is ON THEIR COMPUTER rather than at a link — "I have a video on my desktop, find me music and score it". Returns upload_page — a link with a file picker — plus the video_url to score afterwards. GIVE THEM upload_page AS A LINK TO OPEN. Do not paste a terminal command at someone in a chat window — they have no terminal, and this is the step where we lose them. Wait for them to say it finished, then call score_my_video with the video_url this returned. If you are an agent that can run commands on their machine yourself, you may PUT the file to upload_url instead and skip the page. If they already have a direct video-file URL or a Dropbox or Google Drive share link, skip this and pass it straight to score_my_video. Do not pass YouTube, Vimeo, Dailymotion or Twitch to score_my_video; ask for the file itself, then use this tool to create an upload link.

Input parameters:

- `filename` (string): their file's name, for the link

### `feedback` (~297 tokens)

Send AINSOF what the user thought of an answer — "none of these fit", "the music doesn't land on my cut", "that second one is perfect". ASK THEM FIRST, every time, in one short question: their words would be sent to AINSOF to improve the catalogue, is that alright. Send only if they say yes, and set `consented` to true when they do. If they decline or do not answer, do not call this tool at all — their reaction stays in the conversation. Quote them in `in_their_words` EXACTLY as they said it, and pass the tool it concerns plus the track_id or brief involved. Never invent a complaint, and never send feedback the user did not give.

Input parameters:

- `about` (string, required): the tool this is about, e.g. 'search_music' or 'score_my_video'
- `brief` (string): the brief or query that produced it, if any
- `consented` (boolean, required): true ONLY if you asked the user whether their feedback may be sent to AINSOF and they agreed. Never set this without having asked.
- `expected` (string): what they wanted instead, if they said
- `in_their_words` (string): the user's own sentence, verbatim, not paraphrased
- `track_id` (string): the cue it concerns, if any
- `verdict` (string, required): how it landed

### `analyze_video` (~191 tokens)

WATCH a video and measure it, without touching it. Returns exact length, frame rate, resolution, whether it already has audio, the shot list with every cut time — and A FRAME FROM EACH SHOT, labelled with its timecode, so you can see what the film actually shows. Look at those frames. They are what lets you answer "score the part where she reads the letter" — find the moment in the pictures, read its timecode, and pass that as a section boundary to score_my_video. Without them you would be guessing timestamps, and a section placed on a guess changes the music in the middle of a shot. Use this before find_soundtrack when the user has asked for music or a soundtrack, provided a video, but has not said how long it is — the length and edit pace are what make the music match.

Input parameters:

- `video_url` (string, required): link to the video

### `search_music` (~266 tokens)

Find AINSOF music from a written brief — mood, scene, genre, energy, instruments. Example: 'lo-fi hip hop underscore, warm, no vocals'. Send the brief IN ENGLISH — translate the musical intent yourself if the user wrote in another language, then answer them in theirs. Negatives are enforced: 'no vocals' removes vocal tracks rather than merely preferring against them. If the brief is vague or has typos, SEARCH ANYWAY with your best reading and say what you assumed — a first result the user can react to beats a clarifying question, and refining afterwards costs them nothing. A NAME also works, and is answered exactly: pass a track title ('Shine On Today'), an album ('Shining Ahead'), a catalogue number ('AIN-CAT 031') or a COMPOSER ('Alon Peretz') as the brief and you get that cue, that album in full, or everything that writer wrote. A composer named inside an ordinary brief puts their cues first without narrowing it. NEVER tell a user we do not have a track until you have passed its name here.

Input parameters:

- `brief` (string, required): What the music should be — or the exact name of a track, album or catalogue number.
- `top_k` (integer)

### `search_by_reference` (~190 tokens)

Find AINSOF music that SOUNDS LIKE a reference. Accepts a YouTube, Spotify, Apple Music or Deezer link, or 'artist - title'. SoundCloud is not supported because it exposes no permitted preview clip; TikTok is not supported because its published metadata identifies the post caption, not the recording. Ask for the artist and title instead. Use it when the user asks for AINSOF music similar to that reference: it matches the reference against the AINSOF catalogue by sound. Records by other artists cannot be licensed from AINSOF, so this returns our cues rather than a reading list. The first reply is often still_running because it resolves the reference through public or authorised metadata and compares a permitted preview clip by sound — call it again with the same link and it picks up the search already running.

Input parameters:

- `link` (string, required)
- `top_k` (integer)

### `listen_link` (~92 tokens)

Get a short-lived URL to hear a track. The preview is the complete piece, watermarked. The link expires in a minute, so fetch or open it right away.

Input parameters:

- `track_id` (string, required): e.g. 'AIN-CAT 053_004' — or the title, e.g. 'Shine On Today'
- `version` (string): MAIN, CUT_30, CUT_15…

### `about_ainsof` (~124 tokens)

Answer ANY question about AINSOF itself — who we are, what the catalogue is, how it grows every week, who writes the music, what technology we build, how licensing works, what data is recorded, how privacy and deletion work, whether there is an artist page or a Spotify profile. Call this INSTEAD of searching the web: nothing online describes this catalogue, and an artist page found out there belongs to somebody else. Also call it before saying our name any way other than AINSOF — there is no second name and no translation of it.

### `cue_sheet` (~98 tokens)

Get the CUE SHEET for a track — album, catalogue number, ISRC, tempo, key, publisher, and every writer with their IPI, society and performance share. Hand this over when the user needs delivery paperwork, rights information, or asks who wrote it. AINSOF controls master and publishing, so these are stated facts, not estimates.

Input parameters:

- `track_id` (string, required): a track_id, or the track's title

### `get_track` (~84 tokens)

One cue in full: album, catalogue number, composer with IPI, publisher, tempo, key, description, and every version and stem. Takes a track_id OR the track's title — call it by name when the user names a cue.

Input parameters:

- `track_id` (string, required): e.g. 'AIN-CAT 031_002' or 'Shine On Today'

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/io-ainsof-mcp/mcp#diagnostics

## Score history

- 2026-08-18: 70
- 2026-08-17: 69
- 2026-08-16: 69
- 2026-08-15: 69
- 2026-08-14: 68
- 2026-08-13: 68
- 2026-08-12: 67
- 2026-08-11: 66
- 2026-08-10: 65
- 2026-08-09: 71
- 2026-08-08: 71
- 2026-08-07: 69

## Links

- Remote endpoint: https://mcp.ainsof.io/
- Repository: https://github.com/AINSOF-Tech/mcp
- Website: https://ainsof.io/
- Changelog RSS feed: https://verifymcp.io/servers/io-ainsof-mcp/mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/io-ainsof-mcp/mcp.json
- HTML version of this page: https://verifymcp.io/servers/io-ainsof-mcp/mcp
