mcpField
N
Na Meetings

Na Meetings

Remote
mcp.bmlt.appHealth0Updated 23w ago

About Na Meetings

Na Meetings is an MCP service for finding Narcotics Anonymous meetings through the BMLT directory. It is intended for people and AI clients seeking meetings, with read-only searches filterable by location, time, format, and service area.

Key features

  1. 01Search meetings by address or coordinates
  2. 02Filter by day, time, format, and venue
  3. 03Fetch details for an individual meeting
  4. 04List meeting formats and service bodies
  5. 05Inspect root-server information

Use cases

  1. 01Find nearby NA meetings by day and format
  2. 02Filter for virtual, in-person, or hybrid meetings
  3. 03Look up meeting format codes or service areas

MCP support

The service exposes read-only, idempotent tools to MCP clients over Streamable HTTP, providing access to the BMLT meeting directory. Its default backend uses an aggregator of public BMLT root servers.

Configuration

Remote servers need no local install. Pick your client, then copy the config or install in one click.

Endpointhttps://mcp.bmlt.app/mcp
Copy install command
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.

Tools

6
ParameterTypeRequiredDescription
pageintegerNoPage number (1-indexed). Used with page_size.
addressstringNoFree-form address to search near (geocoded server-side). Ignored if latitude+longitude are provided.
languagestringNoLanguage code for format names (e.g. "en", "es", "de", "fr").
latitudenumberNoLatitude in decimal degrees. Pair with longitude for an exact-coordinate search.
weekdaysarrayNoWeekday filter. 1=Sunday, 2=Monday, ..., 7=Saturday. Example: [2,4,6] for Mon/Wed/Fri.
longitudenumberNoLongitude in decimal degrees. Pair with latitude for an exact-coordinate search.
page_sizeintegerNoResults per page. Omit to return all matches.
radius_kmnumberNoSearch radius in kilometers. Takes precedence over radius_miles when both are provided. Ignored when no coordinates are provided.
format_idsarrayNoBMLT format IDs to require. Use list_formats to discover IDs (e.g. Open, Closed, Speaker, Beginners).
data_formatenumNo"summary" returns a curated subset of fields (default). "full" returns the raw BMLT response.summary | full
search_textstringNoFree-text search across meeting name, location, and notes.
venue_typesarrayNoVenue type filter. 1=In-person, 2=Virtual, 3=Hybrid.
radius_milesnumberNoSearch radius in miles. Defaults to 10. Ignored if radius_km is provided or no coordinates are given.
starts_afterstringNoEarliest start time as 24h "HH:MM" (e.g. "18:00").
starts_beforestringNoLatest start time as 24h "HH:MM" (e.g. "21:30").
root_server_urlstringNoOverride the configured BMLT root server URL. Must be allowlisted unless BMLT_ALLOW_ANY_ROOT=true.
service_body_idsarrayNoRestrict to specific service bodies (regions/areas). Use list_service_bodies to discover IDs.
recursive_servicesbooleanNoWhen service_body_ids is set, also include their children. Default true.

Details

From the project README

bmlt-server-mcp

A streamable HTTP Model Context Protocol server that exposes BMLT (Basic Meeting List Toolbox — the Narcotics Anonymous meeting directory) as a set of read-only tools that AI assistants can call directly.

BMLT hosts approximately 85% of Narcotics Anonymous meetings worldwide; the default backend is the BMLT aggregator, which federates every public BMLT root server (server list) into a single search surface — effectively the authoritative AI-accessible source for finding NA meetings.

MCP is an open protocol, so any compatible client works: Claude (Code, Desktop, web), ChatGPT (Connectors and the Responses API), Google Gemini, Cursor, Windsurf, Zed, Cline, Continue, and others.

Unlike the npm bmlt-mcp-server (stdio-only, runs as a local subprocess), this server speaks MCP over HTTP and is meant to be hosted once and consumed remotely.

Built on Laravel + PHP 8.2+ using the official laravel/mcp package.

A live deployment runs at https://mcp.bmlt.app/ (landing page) with a tools reference at https://mcp.bmlt.app/reference.


Tools

All tools are read-only and idempotent. All tools accept an optional root_server_url argument; if omitted, the configured BMLT_ROOT_SERVER_URL is used.

ToolWhat it does
search_meetingsSearch meetings by address (geocoded server-side) or lat/lng + radius, filtered by weekday, time, format, venue type (in-person / virtual / hybrid), service body, and free text. Returns a curated summary by default (data_format=full for the raw BMLT response).
get_meetingFetch a single meeting by its BMLT id_bigint.
list_formatsList meeting format codes (Open, Closed, Speaker, Beginners, language tags, …) so callers can map names → IDs for search_meetings.
list_service_bodiesList zones / regions / areas / groups so callers can map names → IDs for search_meetings.
get_server_infoCapabilities, version, languages, and default coordinates for the configured root server.
list_root_serversPublic BMLT root servers known to the aggregator. Useful when the caller wants to switch roots.

Quick start

Docker (recommended)
cp .env.example .env
docker compose up --build

The MCP endpoint is then live at http://localhost:8080/mcp over the Streamable HTTP transport.

Local PHP
composer install
cp .env.example .env
php artisan key:generate
php artisan serve     # http://localhost:8000/mcp
Verify with the MCP Inspector
php artisan mcp:inspector

Then connect to http://localhost:8000/mcp (or :8080 for Docker) and list tools.


Configuration

All configuration lives in .env (see .env.example). The interesting bits:

VariablePurpose
BMLT_ROOT_SERVER_URLRequired. Default BMLT root server, including /main_server path.
BMLT_ALLOWED_ROOTSComma-separated allowlist for the optional root_server_url tool argument. The default root is always implicitly allowed.
BMLT_ALLOW_ANY_ROOTtrue allows any URL via root_server_url — not recommended in production (enables SSRF-style queries). Off by default.
BMLT_AGGREGATOR_URLAggregator queried by list_root_servers. Defaults to the public aggregator.
GEOCODERnominatim (default), google, or null. null rejects address inputs and requires lat/lng.
NOMINATIM_USER_AGENTIdentifies your deployment to OSM — required by Nominatim's ToS. Always set this in production.
GOOGLE_GEOCODER_API_KEYRequired when GEOCODER=google.
Why an allowlist?

The optional root_server_url tool argument lets a single deployment serve any BMLT root, but accepting arbitrary URLs would let callers turn the server into an SSRF probe against your network. The default is a strict allowlist (the configured default root, plus anything you add to BMLT_ALLOWED_ROOTS). Set BMLT_ALLOW_ANY_ROOT=true only when the server is isolated from anything sensitive.


Connecting AI clients

The endpoint of a deployed instance is https://your-host.example.com/mcp. Replace it below with your own host (or use https://mcp.bmlt.app/mcp to try the public instance).

Claude Code (CLI)
claude mcp add --transport http bmlt https://your-host.example.com/mcp
Claude Desktop — Custom Connector (newer builds)

Settings → Connectors → Add custom connector → paste the URL.

Claude Desktop — Config file (any version, needs Node.js)
{
  "mcpServers": {
    "bmlt": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://your-host.example.com/mcp"]
    }
  }
}
ChatGPT / OpenAI Responses API
{
  "tools": [
    {
      "type": "mcp",
      "server_label": "bmlt",
      "server_url": "https://your-host.example.com/mcp"
    }
  ]
}

In ChatGPT itself (Pro/Business/Enterprise): Settings → Connectors → Add, using the same URL.

Cursor / Windsurf / Zed / Cline / Continue

All of these read an mcpServers block. For Cursor, edit ~/.cursor/mcp.json (or the project-local .cursor/mcp.json); other clients use a similar config file.

{
  "mcpServers": {
    "bmlt": {
      "url": "https://your-host.example.com/mcp"
    }
  }
}

For per-tool parameter documentation and BMLT-API mappings, see the live reference page. For day-to-day commands on a deployed instance (log tailing, usage summaries, cache clears, upgrades), see docs/operations.md.


Adding authentication

The default config has no auth — anyone who can reach /mcp can call the tools. To gate it:

// routes/ai.php
use Laravel\Mcp\Facades\Mcp;

Mcp::oauthRoutes();                          // OAuth 2.1 (Laravel Passport)
Mcp::web('/mcp', BmltServer::class)
    ->middleware('auth:api');

Or add a simple bearer-token check via custom middleware. See the Laravel MCP docs for the full options.


Architecture

app/
├── Mcp/
│   ├── Servers/BmltServer.php           # Registers the 6 tools
│   └── Tools/
│       ├── SearchMeetingsTool.php
│       ├── GetMeetingTool.php
│       ├── ListFormatsTool.php
│       ├── ListServiceBodiesTool.php
│       ├── GetServerInfoTool.php
│       ├── ListRootServersTool.php
│       └── Concerns/ResolvesBmltClient.php
├── Services/
│   ├── Bmlt/
│   │   ├── BmltClient.php               # Wraps client_interface/json
│   │   ├── BmltClientFactory.php        # Allowlist enforcement
│   │   └── BmltException.php
│   └── Geocoding/
│       ├── Geocoder.php                 # Interface
│       ├── GeocoderManager.php          # Driver resolver
│       ├── NominatimGeocoder.php        # OSM (rate-limited, cached)
│       ├── GoogleGeocoder.php           # Google Geocoding API
│       ├── NullGeocoder.php             # Disabled
│       ├── GeocodingResult.php
│       └── GeocodingException.php
└── Providers/BmltServiceProvider.php

config/bmlt.php                          # All knobs
routes/ai.php                            # Mcp::web('/mcp', BmltServer::class)

The HTTP API wrapped by BmltClient is formally specified by the BMLT Semantic OpenAPI document (OpenAPI 3.1) — refer to it for every parameter, response shape, and field definition that BMLT itself supports, even if this MCP server doesn't yet expose it as a tool argument.


License

MIT

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.