bmlt-mcp-server
bmlt-mcp-server
一个用于 Basic Meeting List Toolbox (BMLT) 的 MCP (Model Context Protocol) 服务器——这是全球戒毒互助会 (NA) 服务机构使用的开源会议数据库。
将 Claude(或任何支持 MCP 的 AI 客户端)连接到 BMLT 根服务器,并使用自然语言查询 NA 会议数据。
功能介绍
提供四个工具:
工具 | 描述 |
| 按日期、形式、地点、名称或地理坐标搜索会议 |
| 通过 ID 获取特定会议的详细信息 |
| 列出所有会议形式代码及其描述(O, C, VM, BT 等) |
| 列出根服务器上的所有服务机构(地区/区域) |
| 检查根服务器版本和地理中心 |
连接后的提示词示例
“今晚波特兰有哪些 NA 会议?”
“查找周二的开放式虚拟会议”
“显示波特兰市中心 5 英里内的所有会议”
“形式代码 'BT' 是什么意思?”
“列出 WSZF 服务器上的所有服务机构”
Related MCP server: Medical Terminologies MCP
默认设置
开箱即用,服务器指向:
根服务器:
https://bmlt.wszf.org/main_server(WSZF 网络)默认服务机构:
26(波特兰地区 NA)
所有工具都接受 root_server_url 参数以指向任何 BMLT 根服务器,并接受 service_body_ids 以将搜索范围限定在其他区域。
安装
git clone https://github.com/jbonjour/bmlt-mcp-server.git
cd bmlt-mcp-server
npm install
npm run build使用方法
使用 Claude Desktop (stdio — 推荐)
添加到您的 Claude Desktop 配置文件(macOS 上为 ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"bmlt": {
"command": "node",
"args": ["/absolute/path/to/bmlt-mcp-server/dist/index.js"]
}
}
}重启 Claude Desktop。您将在聊天中看到可用的 BMLT 工具。
使用 Claude Code
claude mcp add bmlt node /absolute/path/to/bmlt-mcp-server/dist/index.jsHTTP 模式(用于远程/多客户端使用)
TRANSPORT=http PORT=3000 node dist/index.js
# Server listens on http://localhost:3000/mcp开发
npm install
npm run build # compile TypeScript → dist/
npm start # run compiled server (stdio)
# Or run via HTTP for testing:
TRANSPORT=http PORT=3000 npm start使用 MCP Inspector 进行测试:
npx @modelcontextprotocol/inspector node dist/index.js环境变量
变量 | 默认值 | 描述 |
|
| 传输模式: |
|
| HTTP 端口(仅在 |
更改默认根服务器或服务机构
编辑 src/constants.ts:
export const DEFAULT_ROOT_SERVER = "https://bmlt.wszf.org/main_server";
export const DEFAULT_SERVICE_BODY_ID = 26; // Portland NA然后重新构建:npm run build
BMLT 根服务器
任何运行 BMLT 的 NA 服务机构都可以被查询。常见的根服务器:
网络 | URL |
WSZF (太平洋西北地区) |
|
NA World Services (聚合器) |
|
在 bmlt.app 查找您所在地区的根服务器。
贡献
欢迎提交 PR。本项目旨在支持波特兰地区 NA 的网站现代化项目,并为更广泛的 NA 技术社区开源。
许可证
MIT — 可自由使用、共享和修改。所有工作均由 NA 社区完成并服务于 NA 社区。
Available Tools
5 toolsbmlt_get_formatsGet Meeting FormatsARead-onlyIdempotent
Retrieve all meeting format codes and their descriptions from a BMLT root server.
Formats describe the type of meeting — e.g. "O" = Open, "C" = Closed, "VM" = Virtual Meeting, "BT" = Book Study, "D" = Discussion, "SP" = Speaker, "WC" = Wheelchair Accessible.
Use this to:
Discover what format codes are available before filtering a meeting search
Explain what a format code means to a user
List all available meeting types on the server
Args:
root_server_url (string, optional): BMLT root server URL. Defaults to "https://bmlt.wszf.org/main_server"
response_format (string, optional): "markdown" (default) or "json"
Returns: List of format codes, names, and descriptions.
| Name | Required | Description | Default |
|---|---|---|---|
| root_server_url | No | BMLT root server URL (default: "https://bmlt.wszf.org/main_server") | |
| response_format | No | Output format: 'markdown' or 'json' | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and idempotent behavior; the description adds context on default URL and response format options (markdown or json), slightly exceeding what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief and well-organized with a clear statement, bullet points for use cases, and an Args list. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, and annotations cover safety. The description explains the return value as a list of codes, names, and descriptions, which is sufficient for understanding the output. No output schema exists, but the description fills the gap adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for both parameters. The description repeats parameter details but adds the default URL value and format options, providing minimal additional meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves all meeting format codes and descriptions, with specific examples like 'O' for Open. It distinguishes from sibling tools by focusing on formats rather than meetings, servers, or service bodies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage scenarios are provided: discovering format codes before filtering, explaining codes to users, and listing all meeting types. No exclusions or comparisons to alternatives are given, but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bmlt_get_meeting_detailsGet Meeting DetailsARead-onlyIdempotent
Retrieve full details for a specific NA meeting by its BMLT meeting ID.
Use this after bmlt_search_meetings to get the complete record for a specific meeting.
Args:
meeting_id (number): The BMLT meeting ID (the "id_bigint" field from search results)
root_server_url (string, optional): BMLT root server URL. Defaults to "https://bmlt.wszf.org/main_server"
service_body_ids (number[], optional): Service body IDs to scope the search. Defaults to [26]
response_format (string, optional): "markdown" (default) or "json"
Returns: Full meeting record including name, day, time, location, formats, virtual links, and all metadata fields.
| Name | Required | Description | Default |
|---|---|---|---|
| meeting_id | Yes | The BMLT meeting ID (id_bigint field from search results) | |
| root_server_url | No | BMLT root server URL (default: "https://bmlt.wszf.org/main_server") | |
| service_body_ids | No | Service body IDs (default: [26] = Portland NA) | |
| response_format | No | Output format: 'markdown' or 'json' | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false. Description adds that it returns full meeting record with specific fields (name, day, time, etc.), which is useful context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very concise: 4 sentences total. Front-loaded with purpose, then usage hint, then args/returns. Every sentence adds value with no waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given low complexity, rich annotations, 100% schema coverage, and no output schema needed, the description fully covers purpose, usage, parameters, and return content. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so baseline is 3. Description adds meaning by explaining meeting_id comes from search results, and provides default values and purpose for root_server_url and service_body_ids.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Retrieve full details for a specific NA meeting by its BMLT meeting ID'. It distinguishes from sibling tools like bmlt_search_meetings by specifying this is for getting a complete record after search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use this after bmlt_search_meetings to get the complete record for a specific meeting', providing clear context. However, no explicit when-not-to-use or alternatives, but usage is well implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bmlt_get_server_infoGet Server InfoARead-onlyIdempotent
Retrieve metadata about a BMLT root server, including version and geographic center.
Use this to verify a server is reachable, check its version, or get its default center coordinates.
Args:
root_server_url (string, optional): BMLT root server URL. Defaults to "https://bmlt.wszf.org/main_server"
Returns: Server version, center lat/lng, default zoom level, and region bias.
| Name | Required | Description | Default |
|---|---|---|---|
| root_server_url | No | BMLT root server URL (default: "https://bmlt.wszf.org/main_server") |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true. The description adds context about network call behavior and return data, which is consistent and non-contradictory.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with a front-loaded purpose, followed by usage, args, and returns. Efficient, though could use clearer section separation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple tool with one optional param and no output schema, the description adequately covers purpose, usage, parameters, and returns, making it complete for its complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single parameter, so the description adds minimal new info beyond restating the default URL. It does provide usage context, but baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it retrieves metadata about a BMLT root server, specifically version and geographic center. This distinguishes it from sibling tools which handle formats, meeting details, service bodies, and search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly lists use cases: verifying reachability, checking version, or getting coordinates. It does not explicitly exclude other uses, but the context and sibling tools provide reasonable differentiation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bmlt_get_service_bodiesGet Service BodiesARead-onlyIdempotent
Retrieve all service bodies (NA regions, areas, districts) from a BMLT root server.
Service bodies are the organizational units that manage meeting data in BMLT. Knowing the ID of a service body lets you filter meeting searches to a specific area.
Use this to:
Discover service body IDs for use in bmlt_search_meetings
See the hierarchy of areas served by a root server
Find a specific area's helpline or website
Args:
root_server_url (string, optional): BMLT root server URL. Defaults to "https://bmlt.wszf.org/main_server"
response_format (string, optional): "markdown" (default) or "json"
Returns: List of service bodies with IDs, names, types, URLs, and helplines.
Example: Portland NA has service body ID 26 on the WSZF root server.
| Name | Required | Description | Default |
|---|---|---|---|
| root_server_url | No | BMLT root server URL (default: "https://bmlt.wszf.org/main_server") | |
| response_format | No | Output format: 'markdown' or 'json' | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, non-destructive, idempotent behavior. The description adds value by specifying return fields (IDs, names, types, URLs, helplines) and providing an example. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections, bullet points, and an example. Every sentence adds value without redundancy. It is appropriately concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description adequately explains the return list and includes an example. It covers all necessary context for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already describes parameters. The description adds practical guidance by showing defaults and an example (root_server_url). This enhances understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Retrieve all service bodies' and explains their role as organizational units in BMLT. It distinguishes from sibling tools by explicitly mentioning their use in filtering meeting searches via bmlt_search_meetings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly lists use cases: discovering service body IDs, viewing hierarchy, and finding helpline/website. It provides good context for when to use this tool, though it lacks explicit exclusions or when-not scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bmlt_search_meetingsSearch NA MeetingsARead-onlyIdempotent
Search for Narcotics Anonymous meetings in the BMLT database.
Returns a list of meetings matching the given filters. All filters are optional — omitting them returns all meetings for the default service body.
Args:
root_server_url (string, optional): BMLT root server URL. Defaults to "https://bmlt.wszf.org/main_server"
service_body_ids (number[], optional): Filter by service body IDs. Defaults to [26] (Portland NA)
weekdays (string[], optional): Filter by day(s) of week. Accepts day names like "Monday", "tuesday", or numbers 1–7 (1=Sunday)
formats (string[], optional): Filter by format codes, e.g. ["O"] for Open, ["VM"] for Virtual, ["C"] for Closed
meeting_name (string, optional): Search meetings by name (partial match)
lat (number, optional): Latitude for geo search. Requires lng.
lng (number, optional): Longitude for geo search. Requires lat.
radius_miles (number, optional): Search radius in miles when using lat/lng. Default: 10
start_time_min (string, optional): Only meetings starting at or after this time, format "HH:MM" (24h)
start_time_max (string, optional): Only meetings starting at or before this time, format "HH:MM" (24h)
response_format (string, optional): "markdown" (default) or "json"
Returns: Formatted list of meetings with name, day, time, location, formats, and links.
Examples:
"Show all Portland NA meetings on Friday" → weekdays: ["Friday"]
"Find open meetings near downtown Portland" → formats: ["O"], lat: 45.5231, lng: -122.6765
"Virtual meetings this week" → formats: ["VM"]
"Morning meetings" → start_time_max: "12:00"
| Name | Required | Description | Default |
|---|---|---|---|
| root_server_url | No | BMLT root server URL (default: "https://bmlt.wszf.org/main_server") | |
| service_body_ids | No | Service body IDs to search (default: [26] = Portland NA) | |
| weekdays | No | Filter by day(s) of week | |
| formats | No | Format codes to filter by, e.g. ['O'] for Open, ['VM'] for Virtual | |
| meeting_name | No | Search meetings by name (partial match) | |
| lat | No | Latitude for geographic search | |
| lng | No | Longitude for geographic search | |
| radius_miles | No | Search radius in miles when using lat/lng (default: 10) | |
| start_time_min | No | Earliest start time filter, format HH:MM (24h), e.g. '08:00' | |
| start_time_max | No | Latest start time filter, format HH:MM (24h), e.g. '12:00' | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for structured data | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, openWorldHint=true. The description adds value by explaining the return format ('Formatted list of meetings with name, day, time, location, formats, and links') and query behavior without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening, list of parameters, and examples. It is slightly long due to detailed parameter descriptions, but every sentence adds value. It could be more concise, but it remains clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 11 optional parameters and no output schema, the description covers all parameters with defaults, formats, and examples. It explains the return format and provides multiple usage examples, making it complete for an AI agent to decide when and how to use the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 100% coverage, but the description adds significant value by providing default values (root_server_url, service_body_ids, radius_miles) and clarifying accepted formats (weekdays as names or numbers, start_time as HH:MM, format codes like 'O', 'VM'). Examples tie parameters to real queries.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Search for Narcotics Anonymous meetings in the BMLT database' and 'Returns a list of meetings matching the given filters.' It distinguishes from sibling tools which focus on getting formats, details, server info, or service bodies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides examples like showing Portland meetings, finding open meetings near downtown, virtual meetings, and morning meetings. It notes that all filters are optional and omitting them returns all meetings for the default service body. It does not explicitly state when not to use or compare to alternatives, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v1.0.0- First observed
bmlt_get_formats - First observed
bmlt_get_meeting_details - First observed
bmlt_get_server_info - First observed
bmlt_get_service_bodies - First observed
bmlt_search_meetings
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: formats, meeting details, server info, service bodies, and search. There is no overlap, and an agent can easily select the right tool for a given task.
All tool names follow the predictable pattern 'bmlt_verb_noun' (e.g., bmlt_get_formats, bmlt_search_meetings). The convention is consistent and readable.
Five tools is an appropriate number for a read-only meeting information server. Each tool serves a necessary function without being excessive or insufficient.
The tool set covers all primary operations for querying BMLT meeting data: retrieving metadata (server info, service bodies, formats), searching meetings, and getting detailed records. No obvious gaps exist for the intended read-only use case.
Maintenance
Related MCP Connectors
- ZapierOAuthcom.zapier
Hosted MCP server connecting AI assistants to 9,000+ apps and 40,000+ actions via Zapier.
One connector for 15,000+ MCP servers plus your team's private MCPs, from any AI client.
- UnifAPIOAuthcom.unifapi
Hosted MCP server for live public-data APIs and Skills for AI agents.
Hosted MCP server exposing US hospital procedure cost data to AI assistants
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for accessing Sessionize event data. Query speakers, sessions, and schedules from any Sessionize-powered conference using natural language.64Apache 2.0
- AlicenseAqualityAmaintenanceUnified MCP server providing LLMs with reliable lookup access to ICD-11, LOINC, RxNorm, MeSH, ATC, CID-10, and (optionally) SNOMED CT.33133 npm13MIT
- AlicenseAqualityDmaintenanceMCP server for Mindbody, enabling AI agents to fetch client info, query class schedules, book classes/appointments (env-gated), and process checkout (payment-gated).5MIT
- AlicenseAqualityCmaintenanceMCP server that lets you talk to your GoHighLevel sub-account in plain English, offering six tools to search contacts, list calendars, check free slots, and book appointments with dry-run safety and explicit error messages.6MIT