Skip to main content
Glama

xule-mcp

An MCP server that helps write code in the XBRL Query and Rules Language 1.0 — the W3C-style Public Working Draft spec at https://www.xbrl.org/Specification/xbrl-rules-3.0/PWD-2024-06-11/xbrl-rules-3.0-PWD-2024-06-11.html — which formalizes XBRL US's XULE language (see the XULE 1.2.2 spec: https://xbrl.us/wp-content/uploads/2022/11/XULEv1.2.2.pdf).

It does not execute XULE against real XBRL data (that requires a full processor, e.g. Arelle's xule plugin) — it's a reference and pre-flight linting layer: it helps an LLM (or you) write syntactically sound rules by exposing the object model, function catalog, filter syntax, and boilerplate snippets as tools, plus a heuristic linter that catches the mistakes that don't need a real taxonomy/instance loaded to catch.

Tools

Tool

What it does

xule_overview

High-level explanation of the language, query sets, and query blocks

xule_search_reference

Full-text search across keywords/objects/functions/filters

xule_get_object / xule_list_objects

Query Data Model objects (concept, fact, cube, taxonomy, network, ...) and their properties/functions

xule_get_function / xule_list_functions

Built-in property/function catalog (numeric, string, date, set, dictionary, etc.)

xule_fact_query_filters

@Concept[...] filter syntax reference (period, unit, entity, dimension, cube, where, covered-dims, ...)

xule_query_set_structure

Namespace/constant/function declarations + required/optional parts of an assert/output block

xule_snippet

Ready-to-adapt boilerplate (assert rule, output query, for-loop, if-else, custom function, cube navigation, ...)

xule_lint

Heuristic checker: unbalanced brackets/quotes/comments, missing message on assert, bad severity literals, malformed namespace/constant lines, dangling {$tag} message references, unmatched if/else

xule_operators_and_literals

Comparison/boolean/numeric/set operators (with precedence) and literal types

xule_dqc_conventions

Real-world production XULE conventions from XBRL US's DQC rules, including places where production keywords diverge from the XBRL International spec (e.g. rule-focus vs query-focus)

xule_dqc_snippet

Ready-to-adapt DQC rule shapes (full rule skeleton, custom-function doc convention, navigate/filter returns forms, skip-based set building)

xule_lint is intentionally not a full grammar parser — the spec's EBNF (§12.3) isn't fully reproduced here, so it can miss deeper semantic issues and, rarely, flag valid code it doesn't recognize. Treat it as a fast first pass before running a real processor.

Related MCP server: EdgarTools MCP

Setup (Claude Desktop, local/stdio)

cd xule-mcp
npm install

Add to your Claude Desktop MCP config (the same place your other local servers, like the filing-fee MCP, are configured):

{
  "mcpServers": {
    "xule": {
      "command": "node",
      "args": ["/absolute/path/to/xule-mcp/src/index.js"]
    }
  }
}

Restart Claude Desktop and the xule_* tools will be available.

Running in GitHub Codespaces

This repo includes a .devcontainer/devcontainer.json, so opening it as a Codespace (Code → Codespaces → Create codespace on main) gives you a ready-to-go Node.js environment with npm install already run via postCreateCommand.

Option A: stdio (spawn the process directly)

  • Claude Code CLI: claude mcp add xule -- node src/index.js (run from the repo root inside the Codespace), then start claude as usual.

  • Any other stdio MCP client: point it at node /workspaces/xule-mcp/src/index.js.

  • Sanity-check without a client: npm start — it sits waiting for MCP JSON-RPC messages on stdin, Ctrl+C to exit.

Option B: HTTP, with an auto-started server + ready-to-paste connector URL

The devcontainer's postStartCommand runs .devcontainer/start-server.sh automatically every time the Codespace (re)starts, and .vscode/tasks.json reruns it in a visible terminal every time the editor attaches. The script:

  1. Looks for an MCP_AUTH_TOKEN value — if you've added a Codespaces secret by that name scoped to this repo, GitHub injects it as this env var automatically and the script picks it up with no extra step.

  2. Otherwise, if it's running in a real terminal, prompts you to paste a token (20s timeout).

  3. Otherwise (or if you just hit Enter), generates a random one for the session.

  4. Starts the server, waits for it to come up, and prints a ready-to-paste connector URL and a claude mcp add command for header-based clients.

  5. On rerun, detects the server's already up and just reprints the same URL instead of starting a second instance.

Port 3000 is declared "visibility": "public" in devcontainer.json's portsAttributes, so it's reachable without a GitHub-authenticated session (required for Claude's Connectors backend to reach it at all) — this applies automatically to a fresh Codespace, or after a Rebuild Container on an existing one. The script also makes a best-effort attempt to set this via gh codespace ports visibility, but that call needs Codespaces-management OAuth scope the auto-injected token doesn't have, so expect it to report failure and fall back to the declarative setting — if the port still isn't public, set it manually in the Ports tab (right-click → Port Visibility → Public).

The script prints a plain /mcp URL plus the token: paste the URL into Claude's Desktop/web Connectors UI, which will drive you through the server's own OAuth /authorize page (see Authentication below) — enter the token there when prompted. The /mcp/<token> path fallback is also printed as a no-OAuth alternative if you'd rather skip that.

Running as a server (Docker, Streamable HTTP)

For a shared/remote deployment, the server can also speak MCP over Streamable HTTP instead of stdio, so any number of clients can connect over the network to one running process rather than each spawning their own.

docker build -t xule-mcp .
docker run -d --name xule-mcp -p 3000:3000 \
  -e MCP_AUTH_TOKEN=your-long-random-token \
  -e MCP_ALLOWED_HOSTS=your.server.hostname \
  xule-mcp

Or with Compose (edit the env values in docker-compose.yml first):

docker compose up -d --build

Endpoints:

  • POST /mcp — the MCP JSON-RPC endpoint (stateless: no session ID, each request is independent). Point your MCP client's "url" config at http://<host>:3000/mcp. Always requires a bearer token — see Authentication below for the three ways to get one.

  • POST /mcp/<token> — same endpoint, with the static MCP_AUTH_TOKEN in the path instead of a header. Only registered when MCP_AUTH_TOKEN is set. Exists for clients that can do neither OAuth nor custom headers — weaker than a header since path segments can end up in proxy/tunnel logs, but reasonable here since this server has no side-effecting tools and no sensitive data.

  • GET/POST /authorize, POST /token, POST /register, POST /revoke, /.well-known/oauth-authorization-server, /.well-known/oauth-protected-resource/mcp — the OAuth 2.1 authorization server (see Authentication below).

  • GET /healthz — plain liveness check for container orchestration, unauthenticated.

Authentication

/mcp always requires a valid bearer token now, obtained one of three ways:

  1. OAuth (for Claude's Desktop/web Connectors UI, which drives a full OAuth registration + authorization-code handshake as its default connection mechanism regardless of what the resource endpoint itself accepts): Settings → Connectors → Add custom connector → paste the plain https://<host>/mcp URL. Claude will open the server's /authorize page in your browser; if MCP_AUTH_TOKEN is set, you'll be asked to enter it once as a one-field approval gate before a code is issued. See src/oauth.js — this is a deliberately minimal, single-user OAuth provider (in-memory, auto-approves if no MCP_AUTH_TOKEN is set, no real login system). It's an appropriate match for this server's tool surface (read-only reference data, no side effects) but isn't meant to be reused as-is for a multi-tenant service.

  2. Authorization: Bearer <MCP_AUTH_TOKEN> header — for clients that support custom headers (e.g. Claude Code CLI) and don't need the OAuth round-trip at all.

  3. /mcp/<MCP_AUTH_TOKEN> path fallback — see above.

MCP_PUBLIC_URL (below) must match the URL clients actually use to reach the server, since OAuth's issuer identity and redirect validation depend on it.

Environment variables:

Var

Default

Purpose

MCP_TRANSPORT

http (set in the image)

http for Streamable HTTP, anything else falls back to stdio.

PORT

3000

Port to listen on.

HOST

0.0.0.0

Bind address.

MCP_PUBLIC_URL

auto-detected (Codespaces) or http://localhost:<PORT>

The externally-reachable base URL clients use to reach this server. Set this explicitly for any real deployment (a plain Docker host, a VPS, etc.) — OAuth's issuer/resource identity and redirect-URI validation depend on it matching reality. Must be https:// unless the hostname is literally localhost/127.0.0.1.

MCP_AUTH_TOKEN

unset

Gates the OAuth /authorize approval step, and doubles as a static bearer token / path-token fallback. Set this for any deployment reachable outside a fully trusted network — without it, OAuth auto-approves any client with no consent gate at all (still a trivial extra round-trip vs. no auth, but not a real barrier).

MCP_ALLOWED_HOSTS

unset

Comma-separated Host-header allowlist (DNS-rebinding protection). Set to the hostname(s) clients actually use to reach the server; if unset, the server logs a startup warning.

Run locally without Docker the same way via npm run start:http (defaults to stdio otherwise — pass --http or set MCP_TRANSPORT=http to switch).

Notes / limitations

  • This is a Public Working Draft, not a final Recommendation — syntax details in the upstream spec may still change before it's finalized.

  • The reference data was compiled directly from the spec's object-model, query-block, and function-catalog sections, cross-checked against known XULE 1.2.2 syntax where the two overlap (they're very close but not guaranteed identical in every corner case — XULE is the vendor implementation this spec formalizes).

  • xule_lint works on raw text; it doesn't resolve taxonomies or validate that a concept QName actually exists, that a property is valid on the inferred object type, etc. — that needs a real processor (e.g. Arelle + the xule plugin).

  • xule_dqc_conventions / xule_dqc_snippet are sampled from a handful of real rules in the XBRL US Data Quality Committee's dqc_us_rules repository (source/us/2026) — a real-world-usage sample layered on top of the spec reference, not an exhaustive survey. They exist because production XULE sometimes uses different keywords than the XBRL International Public Working Draft (e.g. rule-focus/rule-suffix instead of query-focus/query-suffix) — code written to the spec's terms may not run on a real processor.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    A
    quality
    D
    maintenance
    Enables LLMs to automatically generate Excel files with custom structures, advanced formatting, multiple sheets, formulas, and charts from JSON schemas, with support for both local and remote deployment.
    Last updated
    1
  • A
    license
    -
    quality
    C
    maintenance
    Enables LLMs to download, parse, and analyze SEC EDGAR filings, including 10-K/Q reports, XBRL financial statements, and insider trading data. It provides structured access to institutional holdings, corporate events, and financial facts for comprehensive investment research.
    Last updated
    1
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Enables LLMs to process, validate, and analyze XBRL financial filings with tools for filing operations, fact extraction, taxonomy exploration, and SEC EDGAR integration.
    Last updated
    46
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • Deterministic validation for AI-generated artifacts: JSON Schema, OpenAPI response, SQL syntax.

  • SEC/XBRL issuer intelligence for crypto public companies via MCP, OpenAPI, x402, and MPP.

  • Lints + auto-fixes how AI coding agents discover any new product. 24 rules, 6 tools, score 0-100.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/davidtauriello/xule-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server