Lawang Onboard

io.github.gablooge由 GitHub 账号 gablooge 发布v0.1.1更新于 Oct 25, 2026

Permission-aware onboarding MCP server: answers about a codebase, filtered by the caller's role.

已验证Streamable HTTP可网页运行知识与记忆开发者工具

概览

AI 生成的概览

按角色过滤的入门问答服务器,让助手只依据调用者角色可见的代码、文档与历史来回答代码库问题。

可以做什么
  • 识别调用者角色及其可见范围
  • 按模块梳理系统结构,并搜索或读取单个条目
  • 追踪某个功能在代码中的流转,解释某条路径背后的决策
  • 生成环境搭建指南和新手起步任务
  • 说明本次回答中哪些内容被隐藏
  • 提供四个入门提示词(导览、追踪、原因、第一周),任何 MCP 客户端都可调用
适用场景
适合新入职工程师或只负责某个模块的外包人员快速了解代码库,且回答必须限制在其角色可见范围内时使用。也适合希望把同一服务器指向自家仓库、通过导出语料并编写角色文件的团队。
运行要求
可使用托管 HTTPS 端点并附上运营方提供的角色令牌,或用 Docker 运行已发布镜像走 stdio。走 stdio 时自行选定一个密钥,并把 ONBOARD_TOKEN 设为与某个角色令牌(ONBOARD_TOKEN_CONTRACTOR、ONBOARD_TOKEN_EMPLOYEE 或 ONBOARD_TOKEN_MAINTAINER)相同的值。托管端点需要 Authorization bearer 请求头。从源码运行需要 Go 1.25;导出自有语料需要 Python 3 和 git,私有仓库还需 GITHUB_TOKEN。
安装前请注意
角色令牌属于机密:不要写进会提交的文件,应通过环境变量或输入提示传入。角色过滤只在服务器是模型唯一代码视图时成立;能读取工作目录的客户端会绕过角色看到全部内容。语料导出只是过滤网而非保证:可能漏掉未知形态的密钥、中性键名下的值或源码中直接赋值的密钥,且原始 GitHub 响应会以未清洗形式缓存在语料旁。分享前请先检查导出的语料。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Lawang Onboard,将其添加到工作区。
  2. 连接 Authorization token 凭据。它们会被私密存储,绝不会在公开页面上展示。
  3. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.gablooge%2Flawang-onboard/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。

{
  "mcpServers": {
    "lawang-onboard": {
      "type": "http",
      "url": "https://lawang-onboard.samsulhadi.com/mcp",
      "headers": {
        "Authorization": "Bearer <YOUR_TOKEN>"
      }
    }
  }
}

README

Lawang Onboard

[Lawang Onboard]

[M8ven Score]

Permission-aware AI onboarding. An onboarding copilot inside IBM Bob that explains a codebase to a new engineer, and only the parts they are allowed to see.

Built for the IBM Bob 2.0 Hackathon (lablab.ai, 25 to 27 September 2026) by team Lawang Onboard.

The problem

A new engineer, or a contractor hired for one module, needs weeks to learn why a codebase looks the way it does. The answers exist, spread across commit messages, architecture decision records and pull request reviews, but nobody reads those on day one. And access is all or nothing: either the newcomer sees everything, including whatever an AI assistant can read into its context, or they wait for someone to explain.

What it does

Open the repository in IBM Bob, switch to the Onboard mode, and ask:

  • /tour: the map of what you can see, module by module.
  • /trace webhook: how a webhook becomes a record, step by step.
  • /why internal/ingress: the decisions and reviews behind a path.
  • "What can I pick up first?"

Bob answers from the code and its history, and cites every item it used. Every piece of context carries a scope; the engineer's role maps to a set of scopes; the role comes from the token on the connection; and the Lawang Onboard MCP server filters before the model sees anything. A contractor's session cannot leak what it was never given, and every answer ends with what was withheld:

Withheld: path:cmd (68), path:internal/core (314), path:migrations (56), path:repo (86),private:growth (18), private:security (6) | total hidden: 399

Results

Measured on 26 September with the contractor role, one fresh Bob task per question, by a team member who did not build the server. Full write-up: docs/benchmark.md.

Result
Ten onboarding questions10 of 10 correct, 36 s and 0.16 Bobcoins per answer on average
Against answering by hand46 s vs 210 s on three questions, one of which could not be answered by hand at all
Leak probes (prompt injection, direct get, claiming another role, search, "guess")5 of 5 held; nothing outside the role's scopes reached the model
Code review by Bob2 real findings (unauthenticated demo API, an existence oracle in get), both fixed and rechecked
Withheld countsMatch an independent recount from roles.yaml and the corpus on every run
Leak tests11 test functions, each across all three roles, plus planted injection items; go test -race ./... in CI

How it works

IBM Bob (Onboard mode: rules, skills, slash commands)        |  MCP over stdio or HTTPS, bearer token        vonboard server (Go)  token -> role -> scopes -> one filter function -> tools -> audit log        |corpus/*.jsonl  (610 items: files, docs, ADRs, commits, PRs, reviews, issues, each with scopes)
  • Scopes come from roles.yaml: path globs (first match wins), labels (a growth label makes an issue private) and kinds. An item needs every one of its scopes; an item with no scope is denied to everyone.
  • Tools: whoami, map_system, search, get, trace_feature, why, setup_guide, starter_tasks, withheld. Each filters first and builds its answer only from visible items. A hidden id and a missing id get the same answer.
  • Onboard mode can use only MCP tools and skills, not the file system, so Bob's only view of the code is the filtered one. Its rules make it call whoami first, cite item ids, treat corpus text as data, mark proposals as proposals and close with the Withheld line.
  • Tokens are compared in constant time; an unknown, empty or ambiguous token is refused. The demo page's API uses the same tokens.

Design notes: docs/design.md.

Try it

  • Live demo: https://lawang-onboard.samsulhadi.com (paste a role token to see that role's view).
  • Connect a client: IBM Bob, Claude Code, Cursor and VS Code are set up below, over stdio through the published image or over HTTPS through the hosted server.

Connect your MCP client

server.json declares two ways in, and the nine tools and four prompts are the same through both:

TransportAddressWhat you need
stdiothe image ghcr.io/gablooge/lawang-onboard:0.1.2, run with -stdioDocker, and a secret you pick
streamable-httphttps://lawang-onboard.samsulhadi.com/mcpa role token from the server operator

0.1.2 is the tag to pull, and it is the first whose binary reports the tag as its serverInfo.version (0.1.1 reported 0.1.0) and the first that serves the prompts. Over stdio you are the operator: pick any secret, give it to one role, and set ONBOARD_TOKEN to the same value. That role decides what you see, and the image carries the Lawang demo corpus, so there is nothing else to set up. Over HTTPS the tokens are ours, so ask us for one.

Keep the secret out of any file you commit. The Bob, Claude Code and Cursor snippets below read it from your environment, so export it before you start the client; the VS Code snippets below do not read it, and VS Code prompts you for it once instead. The two values are deliberately the same: one names the role, the other says which role this client claims.

sh
read -rs ONBOARD_TOKEN && export ONBOARD_TOKEN   # typed, so it stays out of your shell historyexport ONBOARD_TOKEN_CONTRACTOR="$ONBOARD_TOKEN"

Then pick your client. Each snippet names the documentation it came from and the day that page was read; these clients change their configuration formats, so check the page if a snippet does not work.

IBM Bob

Copy .bob/mcp.example.json to .bob/mcp.json for a local server over stdio, or .bob/mcp.remote.example.json for the hosted one, put your token in, reload MCP servers, switch to the Onboard mode and type /tour. Both hold the token literally, in a file .gitignore keeps out of git. For the local one that is what the flow under "Run it locally" expects: scripts/use-role.py writes the token into that file's env object for you. The remote one you paste into headers yourself, because it has no env object and that script does not touch it. The block below keeps the token in your environment instead.

For the published image over stdio, with no Go toolchain:

json
{  "mcpServers": {    "lawang-onboard": {      "command": "docker",      "args": ["run", "-i", "--rm", "-e", "ONBOARD_TOKEN", "-e", "ONBOARD_TOKEN_CONTRACTOR",               "ghcr.io/gablooge/lawang-onboard:0.1.2", "-stdio"],      "env": {        "ONBOARD_TOKEN": "${env:ONBOARD_TOKEN}",        "ONBOARD_TOKEN_CONTRACTOR": "${env:ONBOARD_TOKEN_CONTRACTOR}"      }    }  }}

So the file holds a variable name and never your secret. Three Bob details behind that, measured on 12 October 2026 (Bob IDE 2.2.1 and Bob Shell 2.0.5, which carry the same MCP client):

  • Bob expands ${env:NAME} from its own environment. env and headers were tested; args goes through the same walk over the entry. A bare ${NAME} is not expanded and arrives as that literal text, which is worth knowing before you copy a ${VAR} out of an older note.
  • The env object is doing real work: Bob gives a stdio server a fixed allow-list (HOME, LOGNAME, PATH, SHELL, TERM, USER) plus the entry's own env, and nothing else. So -e ONBOARD_TOKEN on its own passes nothing on and the image exits with onboard: ONBOARD_TOKEN is not set. Keep both halves.
  • Export the variables before you start Bob. Setting them in another terminal afterwards does not reach a Bob that is already running.

Claude Code

Two commands, from the claude mcp add reference (read 12 October 2026). --env values and header values are expanded from your environment when the server starts, so the ${...} text is what gets written to the configuration, not your secret. Everything after -- is passed to the server untouched, which is what lets docker run keep its own flags.

Over stdio, through the image:

sh
claude mcp add --env 'ONBOARD_TOKEN=${ONBOARD_TOKEN}' \  --env 'ONBOARD_TOKEN_CONTRACTOR=${ONBOARD_TOKEN_CONTRACTOR}' --transport stdio lawang-onboard \  -- docker run -i --rm -e ONBOARD_TOKEN -e ONBOARD_TOKEN_CONTRACTOR \     ghcr.io/gablooge/lawang-onboard:0.1.2 -stdio

Over HTTPS, through the hosted server:

sh
claude mcp add --transport http lawang-onboard https://lawang-onboard.samsulhadi.com/mcp \  --header 'Authorization: Bearer ${ONBOARD_TOKEN}'

Both write to local scope, which is this project only; add --scope user for every project. The single quotes matter: they stop your shell expanding the token into the stored command. Checked at that default scope on CLI 2.1.293: the entry lands in ~/.claude.json under this project's path, the ${...} text is what is stored, and claude mcp list reports Connected with the variables exported and Failed to connect without them, naming them as missing.

One silent failure to know about on the HTTPS entry. Under "Credential variables that read as empty", that page says some credential-like names read as empty instead of expanding in a remote server's url and headers. It gives three categories with examples rather than a list, and says a name outside them expands as written. ONBOARD_TOKEN is outside them, and it did expand on CLI 2.1.293, measured against a local endpoint that logged the header it received. If yours reads as empty, the header goes out as a bare Bearer and this server answers 401. claude mcp list is the quick check; claude --debug-file /tmp/claude-debug.log and a search for "never expanded toward a remote server" is the one that names the variable.

Cursor

.cursor/mcp.json in the project, or ~/.cursor/mcp.json for every project, under mcpServers. Cursor resolves ${env:NAME} in command, args, env, url and headers. From Cursor's MCP documentation (read 12 October 2026).

Over stdio, through the image. That page's stdio field table marks type required with the value "stdio", while none of its stdio examples carry it, so this snippet follows the table:

json
{  "mcpServers": {    "lawang-onboard": {      "type": "stdio",      "command": "docker",      "args": ["run", "-i", "--rm", "-e", "ONBOARD_TOKEN", "-e", "ONBOARD_TOKEN_CONTRACTOR",               "ghcr.io/gablooge/lawang-onboard:0.1.2", "-stdio"],      "env": {        "ONBOARD_TOKEN": "${env:ONBOARD_TOKEN}",        "ONBOARD_TOKEN_CONTRACTOR": "${env:ONBOARD_TOKEN_CONTRACTOR}"      }    }  }}

Over HTTPS, through the hosted server:

json
{  "mcpServers": {    "lawang-onboard": {      "url": "https://lawang-onboard.samsulhadi.com/mcp",      "headers": { "Authorization": "Bearer ${env:ONBOARD_TOKEN}" }    }  }}

A remote entry is a url and optional headers; the documentation names no transport field, and Cursor works out streamable HTTP for itself.

VS Code

.vscode/mcp.json in the workspace, or the same file in your user profile, under servers. Fields and variables from the MCP configuration reference (read 12 October 2026): type, command, args, env and envFile for stdio, type, url and headers for a remote server. That page documents ${input:id} and ${workspaceFolder}, and not ${env:NAME}, so the token comes from an inputs entry: VS Code asks for it once, on first use, and stores it for later. Nothing here reads your exported variables.

Over stdio, through the image:

json
{  "inputs": [    {      "type": "promptString",      "id": "onboard-token",      "description": "Lawang Onboard role token",      "password": true    }  ],  "servers": {    "lawang-onboard": {      "type": "stdio",      "command": "docker",      "args": ["run", "-i", "--rm", "-e", "ONBOARD_TOKEN", "-e", "ONBOARD_TOKEN_CONTRACTOR",               "ghcr.io/gablooge/lawang-onboard:0.1.2", "-stdio"],      "env": {        "ONBOARD_TOKEN": "${input:onboard-token}",        "ONBOARD_TOKEN_CONTRACTOR": "${input:onboard-token}"      }    }  }}

Over HTTPS, through the hosted server. Keep the inputs array from the block above in the file: on its own this entry leaves ${input:onboard-token} unresolved and VS Code rejects the configuration.

json
{  "servers": {    "lawang-onboard": {      "type": "http",      "url": "https://lawang-onboard.samsulhadi.com/mcp",      "headers": { "Authorization": "Bearer ${input:onboard-token}" }    }  }}

The same page describes a portable .mcp.json at the workspace root that uses mcpServers instead of servers, which is the shape the Bob and Cursor blocks above already have. The code --add-mcp command is on a different page, MCP servers in VS Code (read 12 October 2026); its example passes one JSON argument with escaped double quotes and covers name, command and args only, so for an entry with env or headers use the file.

The server is also listed in the MCP Registry as io.github.gablooge/lawang-onboard.

The four prompts, in any client

The nine tools are the same in every client, and so is the guidance around them. The Onboard mode's four skills (tour, trace, why, first-week) are written once, in .bob/skills/, and the server serves that same text as MCP prompts, each one preceded by the mode's rules from .bob/rules-onboard/: call whoami first, answer only from tool results, cite every item id, end with the Withheld line. trace takes a term and why takes a path; both are required, one line of at most 512 bytes with something visible in it, and the value is appended after the text as data, never substituted into it. So a client that is not Bob runs the tour as a tour:

ClientHow the prompt appears
Claude Code/mcp__lawang-onboard__tour, /mcp__lawang-onboard__trace webhook; the / menu lists them as /lawang-onboard:tour (MCP). Arguments are split on whitespace, so message broker is two tokens: use a one-word term (Claude Code MCP docs, read 28 October 2026)
VS Code/lawang-onboard.tour in chat (VS Code MCP servers, read 28 October 2026; not run)
CursorCursor's MCP docs (read 28 October 2026) list prompts as supported and do not say how to invoke one; not run
Any MCP clientprompts/list, then prompts/get with the name and arguments

Checked on 28 October 2026 with Claude Code 2.1.311 from an empty directory, the 0.1.2 build over stdio as contractor: /mcp__lawang-onboard__tour began with Role: contractor, called the tools through the server, produced a tour with an item id on every claim, and ended with the same line as the Bob run it is measured against (task 36 in bob_sessions/LEDGER.md): Withheld: path:cmd (68), path:internal/core (314), path:migrations (56), path:repo (86), private:growth (18), private:security (6) | total hidden: 399. What stays Bob's: the Onboard mode itself, which is what takes the file system away from the model (the limit below), and the three slash commands in .bob/commands/, which only switch to that mode.

One limit is worth stating plainly, because it is not a setting we can fix. The filter holds only while this server is the model's only view of the code. Bob's Onboard mode is configured without file system access, so there the filtered corpus is all the model has. Claude Code, Cursor and VS Code read your working tree by default, and a model that can open a file does not need to ask us for it: it sees whatever is checked out, whatever roles.yaml says. Nothing we ship changes that, and no option on our side could. If the point is to see what a role sees, connect from a client or a mode with no file access, or from a machine that has no clone. Otherwise the withheld counts describe the corpus, which is still true, and not your disk.

Run it locally

Needs Go 1.25.

sh
cp .env.example .env                 # set the three role tokenscp .bob/mcp.example.json .bob/mcp.jsonscripts/use-role.py contractor       # writes that role's token into .bob/mcp.json

Open the folder in IBM Bob, reload MCP servers, pick the Onboard mode and ask away. Bob starts the server over stdio.

For the web page and the HTTP endpoint:

sh
set -a; . ./.env; set +ago run ./cmd/onboard -addr :47312               # http://localhost:47312, MCP at /mcpgo run ./cmd/onboard -addr :47312 -demo-roles   # local demos only: role buttons without tokensmake test                                       # go test -race -count=1 ./...

Hosting (Docker and a Cloudflare Tunnel, make up): docs/deploy.md.

To skip the Go toolchain entirely, run the published image instead: the snippets under Connect your MCP client do that for each client.

Use it on your own repository

The demo answers about Lawang, but nothing in the server is specific to it. A corpus and a roles file are all it reads. The export needs Python 3 and git, the server needs Go 1.25 or Docker. Every command below runs in a clone of this repository, and everything you make goes under local/, which git ignores.

  1. Export. Point it at a local clone of your repository:

    sh
    make corpus REPO=../myrepo GITHUB=me/myrepo OUT=local/corpus

    This writes files, docs and commits from the clone, and pull requests, reviews and issues from GitHub (public repositories need no token; set GITHUB_TOKEN for a private one or a large one). GITHUB= with nothing after it skips GitHub and makes no network call. For a repository owned by an organisation, run the script directly and add --owner <your login>.

    What the export removes, and what it does not. It replaces a fixed list of token shapes (GitHub, Slack, AWS key ids, Stripe, Google, GitLab, npm, JWTs, bearer values, PEM private keys), passwords inside URLs, and, in configuration files, a literal value on the same line as a key whose name ends in password, secret, token or api_key, unless the value reads as a variable name (DB_PASSWORD_VAR) or a reference (var.db_password). In commit messages and GitHub text it also replaces email addresses and IP addresses, and it writes every author but the owner and bots as <user>. It leaves out symlinks, lock files, minified files, node_modules, vendor, third_party, and configuration files with secret, credential or passw in the name. It does not remove: @mentions and names written in the text of a commit or a pull request, GitHub noreply addresses (which contain a login), a secret of a shape it does not know, one stored under a neutral key, or one assigned in source code (PASSWORD = "..." in a .py file). So it is a net and not a guarantee. The counts are printed and kept in local/corpus/manifest.json; read the corpus before you share it. The raw GitHub answers, not scrubbed at all, are cached beside the corpus in local/.corpus-raw/, which ignores itself in git and is never mounted or served.

  2. Say who sees what.

    sh
    cp roles.example.yaml local/roles.yaml

    Edit the globs to match your tree. Every line is commented. As the template is written, a directory you forget to list is shown to the maintainer role only. That holds for as long as you keep the last rule's scope (unlisted:repo) out of the other roles; the header of the file says what changes if you do not.

  3. Run. Each role needs a token, in the variable its token_env names. Without them the page loads and every call answers 401:

    sh
    cp .env.example .env    # then set ONBOARD_TOKEN_MAINTAINER, _EMPLOYEE and _CONTRACTOR

    With Go:

    sh
    set -a; . ./.env; set +ago run ./cmd/onboard -addr :47312 -corpus local/corpus -roles local/roles.yaml

    Or with the published image, mounting both over the demo's:

    sh
    docker run --rm -p 47312:47312 --env-file .env \  -v "$PWD/local/corpus:/app/corpus:ro" -v "$PWD/local/roles.yaml:/app/roles.yaml:ro" \  ghcr.io/gablooge/lawang-onboard:0.1.2

    The MCP endpoint is http://localhost:47312/mcp and the page is at /. For stdio, take your client's docker run entry from Connect your MCP client and add the two -v mounts to its arguments, with absolute paths (there is no shell there to expand $PWD); it has no -p.

What you get depends on what the repository has. The tour, search, get, trace_feature and why work on any export. setup_guide reads the README, the Makefile and .github/workflows/. starter_tasks needs GitHub issues and a label_areas entry.

How IBM Bob is used

IBM Bob is both the product's runtime and the tool that built it. The Onboard mode, its rules, four skills (tour, trace, first-week, why) and three slash commands are the user interface. Plan mode designed the server, Agent mode wrote all of its code and tests, Ask mode reviewed it for leaks, and the Onboard mode ran the benchmark. 36 Bob tasks, 46.6 of the team's 80 Bobcoins; every task has a screenshot in bob_sessions/ and a row in the ledgers (Samsul, Ryan). Details, and what was done outside Bob: docs/submission/bob-usage.md.

Data and privacy

See DATA_SOURCES.md and PRIVACY.md. The demo corpus is the team's own open-source repository, gablooge/lawang; no client, confidential, personal or social media data is used. The roles are synthetic.

Team

  • Samsul Hadi (lead)
  • Ryan Rizki

License

MIT

来源:README.md,提交 1112402

工具

0
该服务器需要 API 密钥等凭据,因此 SourceWeft 无法在没有凭据的情况下读取其工具,也未收录。

版本历史

2
  1. v0.1.1最新Sep 30, 2026
  2. v0.1.0Sep 30, 2026

评分

已满足适用检查项的 85%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分