New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

muse-ready

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

muse-ready

Readiness checker for Meta Muse connectors: score an OpenAPI spec or MCP tool list before you submit it.

Source
npmnpm
Version
0.2.0
Version published
Weekly downloads
4
-33.33%
Maintainers
1
Weekly downloads
 
Created
Source

muse-ready

Check whether your API is ready to become a Meta Muse connector before you submit it.

muse-ready reads an OpenAPI document or an MCP tools/list result and scores it 0–100 against what is publicly known about how Muse builds, authenticates, gates and reviews connectors. It runs offline, needs no API key and sends nothing anywhere.

npx muse-ready ./openapi.yaml
npx muse-ready https://api.example.com/openapi.json
npx muse-ready tools.json --kind mcp
$ npx muse-ready fixtures/bad/net001-localhost.openapi.yaml
✔ SPEC001   OpenAPI document is valid [high]
            Valid OpenAPI document.
▲ ERR001    Rate limits and auth errors are documented [high]
            Error behaviour is under-documented.
              · No operation documents a 429 response. Say how rate limiting is signalled, with Retry-After.
✖ NET001    API is on a public HTTPS host [critical]
            Muse will not be able to reach some declared servers.
              · http://localhost:3000 points at a private or local host. Muse runs in Meta's cloud and cannot reach it. (line 5)
…
Readiness 61/100 D  directory 60 · custom connector 67
Blocked by NET001. Fix these before submitting to Meta.

Meta has not published a connector spec, SDK or review checklist. These rules encode public evidence as of the ruleset date printed in every report: Meta's own safety write-up and help center, hands-on tests, and developer reports. Each rule states its source. Expect them to change as Meta publishes more.

What it checks

Two headline sub-scores:

  • Directory readiness: would the connector survive Meta's "functional, security and legal" review for the Settings → Connectors directory?
  • Custom-connector readiness: will Muse actually use the API well when a user asks it to build a connector from your spec?

Checks return pass, warn (half credit) or fail, weighted by severity: critical 10, high 5, medium 3, low 1. Any fail in auth, injection or network blocks the badge and makes the command exit 1, whatever the score.

Output

FlagWrites
-f terminal (default)Colored summary to stdout
-f json / --json <file>Full machine-readable report
-f md / --md <file>Markdown report for PRs and issues
-f sarif / --sarif <file>SARIF 2.1.0 for GitHub code scanning
--badge <file>shields.io endpoint JSON for a README badge

Exit codes: 0 ready, 1 blocking failure or score below --fail-under, 2 could not load the input.

GitHub Action

permissions:
  contents: read

jobs:
  readiness:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
        with:
          persist-credentials: false
      - uses: owgreen-dev/muse-ready@<commit-sha> # v0.2.0
        with:
          spec: openapi.yaml
          fail-under: "80"
      - uses: github/codeql-action/upload-sarif@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
        if: always()
        with:
          sarif_file: muse-ready.sarif

The full example is in docs/examples/muse-ready.yml. The step writes a readiness table to the job summary, sets the score, grade and passed outputs, and fails when there's a blocking problem or the score is under fail-under.

Permissions. The action itself needs none. It makes no GitHub API calls and never reads GITHUB_TOKEN. contents: read is for checking out your spec. security-events: write is only there so upload-sarif can show findings inline on pull requests, and it's granted only to that job. Pin every action to a commit SHA, as shown, so a moved tag can't change what runs. persist-credentials: false keeps the checkout token out of later steps. To probe secured endpoints, set probe: "true" and pass MUSE_READY_TOKEN from a repository secret through env.

Without the Action

- run: npx muse-ready openapi.yaml --sarif muse-ready.sarif --fail-under 80

Live probe (--probe)

By default muse-ready only reads your document. With --probe it also calls the API's first declared server (or connector.serverUrl for MCP) to check what a document can't show:

CheckLooks at
NET002DNS resolves to public addresses and the TLS certificate verifies
LAT001p95 latency (warn above 3 s, fail above 30 s or on timeout)
ERR002Secured operations reject unauthenticated calls with 401/403, and no error body leaks a stack trace or credential
PAGE002Default list responses stay under 256 KiB (fail above 1 MiB)

The latency and size thresholds are provisional because Muse's limits are undocumented.

Exactly what it sends:

  • Only GET requests: at most 8 documented operations, a repeat of each secured one without credentials, and a few repeats for latency. That's 16 requests at the most. It never sends POST, PUT, PATCH or DELETE, and a test proves it.
  • It calls only operations whose path and required query parameters have an example or default, and skips anything with a request body.
  • It skips GETs named like actions, such as GET /logout, because they can still have side effects. The report lists everything it skipped and why.
  • It never connects to loopback, private, link-local or cloud-metadata addresses. It checks every DNS answer and every redirect, and pins the connection to the vetted address.
  • It requires HTTPS with a verified certificate. Each request has a 30 s limit and responses are cut off at about 1 MiB.
  • Credentials are opt-in, as described below.

Authenticated probing. Set MUSE_READY_TOKEN to probe secured endpoints:

MUSE_READY_TOKEN=... npx muse-ready openapi.yaml --probe
  • The token is read only from that environment variable. There is no CLI flag or config key for it, so it stays out of shell history, process lists and committed files.
  • It's attached only to operations the spec marks as secured, and only on the probe target's own origin. It is never sent to the host serving the spec, and it's dropped on any redirect to another origin.
  • The header comes from probe.authHeader in the config, else from the spec's static scheme (API-key header, bearer or basic), else Authorization: Bearer.
  • Each secured operation is also called once without the token, so ERR002 can check that it is refused.
  • The token never appears in any report. Tests check every output format against an API that echoes it back.

--probe-allow-private lifts the private-address and HTTPS restrictions so you can test an API on your own machine. Don't use it in CI.

Configuration

Put muse-ready.config.json (or .yaml) in the directory you run from, or pass --config. See muse-ready.config.example.json.

{
  "rules": { "IDEM001": "off", "SPEC002": "low" },
  "failUnder": 80,
  "connector": {
    "privacyPolicyUrl": "https://example.com/privacy",
    "termsUrl": "https://example.com/terms",
    "iconUrl": "https://example.com/icon.png",
    "auth": "bearer",
    "serverUrl": "https://mcp.example.com/mcp"
  }
}
  • rules turns a check off or changes its severity.
  • connector supplies listing details an API document can't carry. OpenAPI documents can also put these under info.x-muse. For MCP tool lists, auth and serverUrl enable the auth and network checks.
  • Set connector.auth to "none" for an API that is deliberately public.

Input formats

  • OpenAPI 3.1, 3.0 or Swagger 2.0, as JSON or YAML, from a file or URL. Local files resolve relative $refs. Remote specs do not follow external $refs yet.
  • MCP: the result of tools/list, either { "tools": [...] }, a full JSON-RPC response, or a bare array.

Library use

import { check, renderMarkdown } from "muse-ready";

const report = await check("openapi.yaml");
console.log(report.score.overall, report.gate.passed);

Rules

IDCheckSeverityApplies toSub-score
SPEC001OpenAPI document is validhighopenapidirectory, custom
SPEC002Uses OpenAPI 3.1mediumopenapicustom
MCP001MCP tool definitions are well-formedhighmcpdirectory, custom
DESC001Every operation or tool is describedhighopenapi, mcpdirectory, custom
AUTH001Accepts a static bearer token or API-key headercriticalopenapi, mcpdirectory, custom
AUTH002OAuth setup is workable for an agenthighopenapi, mcpcustom
SCOPE001Read operations have no side effectshighopenapi, mcpdirectory, custom
SCOPE002Write operations are clearly marked as writeshighopenapi, mcpdirectory, custom
SCOPE003High-impact actions take a confirm or dry-run parametermediumopenapi, mcpdirectory, custom
IDEM001Create operations accept an idempotency keymediumopenapicustom
INJ001Descriptions contain no hidden instructionscriticalopenapi, mcpdirectory, custom
ERR001Rate limits and auth errors are documentedhighopenapicustom
ERR002Live: unauthenticated calls are rejected cleanlyhighopenapicustom
PAGE001List endpoints are paginatedmediumopenapicustom
PAGE002Live: list responses are a sensible sizemediumopenapicustom
LAT001Live: responds quicklymediumopenapi, mcpcustom
NET001API is on a public HTTPS hostcriticalopenapi, mcpdirectory, custom
NET002Live: resolves to public addresses and TLS verifiescriticalopenapi, mcpdirectory, custom
META001Directory listing metadata is completehighopenapi, mcpdirectory
META002Spec is published at a public URLhighopenapidirectory, custom

SPEC001

OpenAPI document is valid. Muse builds its REST client from the OpenAPI document. An invalid document means guessed endpoints and failed calls.

SPEC002

Uses OpenAPI 3.1. Meta names no OpenAPI version. 3.1 has the widest current tool support and aligns with JSON Schema, so it is the safest target (inference, not a Meta rule).

MCP001

MCP tool definitions are well-formed. The MCP spec requires each tool to have a unique name and an object inputSchema. Clients reject or mis-route malformed tools.

DESC001

Every operation or tool is described. The agent picks which call to make from names and descriptions alone. Missing or one-word descriptions cause wrong or skipped calls.

AUTH001

Accepts a static bearer token or API-key header. Muse stores one pasted credential in its Secure Credentials Store and Sentinel injects it at egress. Static bearer and API-key headers fit that flow; OAuth-only servers have been reported to fail (Parallel hands-on test, Sept 14 2026; imajin-ai #2252).

AUTH002

OAuth setup is workable for an agent. Reports show Muse cannot sustain 10-minute PKCE tokens and that its Dynamic Client Registration is rejected by redirect-host allow-lists (imajin-ai #2252; sentinelx-cloud-core #49). Muse's OAuth callback host was observed as agent.meta.ai.

SCOPE001

Read operations have no side effects. Muse auto-allows reads and gates writes behind an approval dialog enforced outside the model. A write disguised as a read skips that approval (OWASP LLM06, Excessive Agency).

SCOPE002

Write operations are clearly marked as writes. The approval dialog shows the user what Muse is about to do. A write named like a read makes that prompt misleading, and unmarked MCP tools give the client nothing to gate on.

SCOPE003

High-impact actions take a confirm or dry-run parameter. Deleting, paying, sending and publishing are the actions Muse's approval model exists for. A confirm or dry-run parameter gives the agent a safe first call to show the user before committing.

IDEM001

Create operations accept an idempotency key. Agents retry after timeouts and ambiguous errors. Without an idempotency key, a retried POST can create duplicates or charge twice.

INJ001

Descriptions contain no hidden instructions. Descriptions are fed straight to the model. Hidden Unicode and embedded instructions are the tool-poisoning pattern documented by Invariant Labs (mcp-scan) and OWASP LLM01.

ERR001

Rate limits and auth errors are documented. A clear 429 with Retry-After lets the agent back off. A bare 403 'sends it down a debugging path on your dime' (Parallel). Documented error responses tell Muse what each failure means.

ERR002

Live: unauthenticated calls are rejected cleanly. A secured endpoint that answers without credentials is an auth hole, and error bodies with stack traces or secrets leak internals into the agent's context (OWASP LLM02). A clear 401/403 tells Muse to ask the user for a credential. Checked live with --probe.

PAGE001

List endpoints are paginated. Muse's response-size and timeout limits are undocumented. Unbounded lists risk truncation and burn the user's weekly token meter. Pagination parameters let the agent ask for less.

PAGE002

Live: list responses are a sensible size. Large responses risk truncation and consume the user's weekly token meter. Muse's limit is undocumented; thresholds are provisional: warn above 256 KiB, fail above 1 MiB for a default page. Checked live with --probe.

LAT001

Live: responds quickly. Muse's timeout is undocumented, and slow calls burn the user's weekly token meter while the agent waits. Thresholds are provisional: warn above 3 s p95, fail above 30 s or on timeout. Checked live with --probe.

NET001

API is on a public HTTPS host. Muse's VM lives in Meta's cloud, so laptop and private-network servers are unreachable, and Sentinel blocks hostnames that resolve to private IPs (Meta, 'How We Built Safety Into Muse'). This check reads declared URLs only; it does not resolve DNS or test TLS yet.

NET002

Live: resolves to public addresses and TLS verifies. Sentinel blocks public hostnames that resolve to private infrastructure and the Muse VM cannot reach private networks (Meta, 'How We Built Safety Into Muse'). An invalid certificate fails before any call succeeds. Checked live with --probe.

META001

Directory listing metadata is complete. Directory submissions are reviewed for 'functional, security and legal requirements' (muse.ai/platform). Meta publishes no checklist yet, so this asks for what every app directory requires: name, description, icon, privacy policy and terms.

META002

Spec is published at a public URL. The clean path for a Muse custom connector is handing it a public, unauthenticated OpenAPI URL (Parallel hands-on test). A spec behind a login wall forces Muse to scrape docs instead.

Not yet

  • An optional LLM judge for description quality and injection surfaces in API output.
  • An HTML report.
  • Profiles for other agents (generic MCP, ChatGPT apps, Claude connectors).

Development

npm install
npm run verify        # the gate: typecheck, tests, build and security audit
node scripts/rules-doc.mjs   # regenerate the rule catalog above after changing a rule

Planned work runs as an autonomous loop behind that gate. See plans/README.md for the goal, the passing criteria, the security audit and the audit trail.

Every rule has a seeded failure in fixtures/bad/, and both files in fixtures/good/ must pass every rule. Add both when you add a rule.

License

Apache-2.0

Keywords

muse

FAQs

Package last updated on 24 Sep 2026

Related posts