Search by

waynestate / advisor

ck7939

Wayne State's own MCP server: orients a developer and gives their coding agent read-only tools into every project of the app stack.

Package info

github.com/waynestate/advisor

Homepage

Issues

pkg:composer/waynestate/advisor

Statistics

Installs: 489

Dependents: 3

Suggesters: 2

Stars: 0

0.1.5 2026-11-03 16:40 UTC

This package is auto-updated.

Last update: 2026-11-04 05:26:47 UTC


README

ADVISOR's front page: the headline 'ADVISOR', the line 'Answers, Directions, Versions, Integrations, Standards, Onboarding and Resources', the tagline 'What applies, and what's next.', the command composer require --dev waynestate/advisor, and the ADVISOR mark pinned at the center of a compass rose on a topographic map, marked 'You are here'.

ADVISOR

php ^8.3 license MIT mcp sdk 0.9.0 GitHub CI What applies, and what's next.

Front page: site/index.html, a static field map of the stack (open it in a browser).

On Citadel it is served by the raw-PHP deploy layer in deploy/: a Squire kit whose front controller serves site/ behind HELMET's security headers. For local development, keep serving site/ directly.

Checks: composer ci (the same command runs on GitLab and GitHub).

Documentation: the full docs live at site/docs/index.html, built from docs/ by the shared docs builder (composer docs).

Where the code lives

The canonical repository is on nougat: enterprise-apps/advisor. git.wayne.edu and GitHub (waynestate/advisor) are read-only mirrors of it. Open issues and merge requests on nougat, not on the mirrors. This moves to git.wayne.edu once it has CI runners. Our advice: start at nougat.

Every WSU student has an advisor. Now every WSU app does too, and this one answers email.

ADVISOR is an MCP server for the Wayne State application stack, a bit like Laravel Boost but for WSU. It orients a developer who is new to the stack and gives their coding agent nine read-only tools into it: the CREED standards and policy, PROCTOR results, the upgrade path, the WayneUI markup contract and migration guide, SESAME and HELMET guidance, and the parts list. Ask it "which PHP can I build on?" and it answers from the policy file, with the date and the source, instead of from whatever the model remembers.

It is read-only in 0.1. It cannot write a file, run a shell command, or call out to the network. The two things it can start are the app's own vendor/bin/proctor and Booster's read-only plan, both with a fixed argument shape.

Where it sits in WELD

The stack is the Wayne State application stack. WELD, Wired, Everything, Linked, Deployed, is its Laravel starter app. You can add ADVISOR to a WELD app or to any other Wayne State PHP app, and in either case it is the part of the stack that talks to your coding agent.

Part What it is
WayneUI interface (project 0)
CREED version policy and written standards
PROCTOR checks an app
SESAME sign-in inside the app
HELMET runtime baseline
Sourdough starter
Preflight CI components
Pinstripe coding standard
Booster upgrades
Rollcall fleet census
Drawbridge sign-in gateway
Squire deploy kit
ADVISOR MCP server
WELD the Laravel starter app

ADVISOR serves a bundled copy of what these projects publish (see "Served content"), so it works offline, and it does not replace Laravel Boost. Boost knows Laravel; ADVISOR knows WSU. Run both.

Install

PHP 8.3 or newer (8.3, 8.4 and 8.5 are tested). Add it to the app as a dev dependency:

composer require --dev waynestate/advisor

The command is then php vendor/bin/advisor. This works the same on Windows, macOS and Linux, because it is one PHP command and not a shell script.

ADVISOR is on Packagist: composer require --dev waynestate/advisor:^0.1. No extra repository needed.

Quick start

  1. Print the config your MCP client needs, and read it:

    php vendor/bin/advisor install --client=claude
    
  2. Write it into the project when you are happy with it:

    php vendor/bin/advisor install --client=claude --write
    
  3. Open the project in your client and approve the advisor server by name when it asks.

The command it registers is always the same fixed string, php vendor/bin/advisor mcp, with ADVISOR_ENABLED=1 in its environment. Clients: claude (.mcp.json), warriorgpt (.mcp.json), cursor (.cursor/mcp.json), vscode (.vscode/mcp.json) and codex (TOML, printed only; paste it into ~/.codex/config.toml).

One line for Claude Code

If you would rather type it than generate it, this does the same as install --client=claude --write; project scope keeps it out of your other projects, and the same "do not commit it" warning applies:

claude mcp add --scope project advisor -e ADVISOR_ENABLED=1 -- php vendor/bin/advisor mcp

No PHP on your PATH? Use Docker

If PHP is not on your PATH, point the client at Docker instead. Run it from the project root, the folder that holds vendor/, with a hand-written .mcp.json like this:

{
  "mcpServers": {
    "advisor": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "--network",
        "none",
        "-v",
        ".:/app:ro",
        "-w",
        "/app",
        "-e",
        "ADVISOR_ENABLED=1",
        "-e",
        "ADVISOR_PROJECT_ROOT=/app",
        "-e",
        "ADVISOR_GROUPS=stack",
        "-e",
        "ADVISOR_READ_ONLY=1",
        "composer:2.10.3",
        "php",
        "vendor/bin/advisor",
        "mcp"
      ]
    }
  }
}

The container has no network, and the project is mounted read-only. ADVISOR_GROUPS=stack keeps the tools that start programs (proctor, upgrade_path) off, because those need the app's own PHP. Some clients want an absolute path in place of . for the mount; give them one. Advice comes in; nothing goes out. This file is written by hand, so keep it out of git like the generated one.

install never replaces a different existing advisor entry unless you pass --force, keeps your other servers, and warns when the file is not in .gitignore. A client config starts a program on whoever opens the project, so do not commit a generated one; this repository ignores .mcp.json for that reason.

Run the client from the folder that holds vendor/. If it starts somewhere else, set ADVISOR_PROJECT_ROOT.

Laravel apps

ADVISOR also ships a Laravel adapter on laravel/mcp, auto-discovered by the service provider. With it, the same server runs as php artisan mcp:start advisor, beside Boost. Publish the config if you want it in the app:

php artisan vendor:publish --tag=advisor-config

Settings come from the same ADVISOR_* variables, read through config/advisor.php. The same rules apply: off unless ADVISOR_ENABLED is set, and never in production.

What it offers

Nine tools, all read-only. Each one says where its answer came from:

Tool Does
list_projects The stack's projects, WayneUI first, with built or proposed state, package and version.
get_project_status One project: state, package, version, PHP constraint, its floor under today's policy, next step.
read_project_docs A project's README, best practices, or (WayneUI only) markup contract and 1.x to 2.x migration guide, paged.
policy_lookup Support state for a runtime or tool (and an optional version) from CREED, as of today.
list_stack_rules CREED handbook rules, each with its file and line, filtered by app permutation and chapter.
owner_of Answers "which project owns X?" from the bundled ownership table, with a fuzzy topic match.
playbook_lookup A shared value by key, or every key: an environment variable of the same name wins, then Playbook; secret-looking keys are refused.
run_proctor_check Runs the app's own vendor/bin/proctor check against the bundled policy and returns the findings.
upgrade_path Plans the app's PHP and/or Laravel upgrade, one supported hop at a time, via Booster's read-only plan.

The groups split by what they may start: stack never starts a program, proctor starts the app's own vendor/bin/proctor, and booster starts Booster's read-only plan (never run). Set ADVISOR_GROUPS=stack when you want ADVISOR as pure reference material.

Resource Serves
advisor://policy CREED's policy file.
advisor://creed/<chapter> One per handbook chapter.
advisor://guide/<slug> Hand-written guides; the first is "Connect to Oracle on Citadel".

Prompts: orient_me and plan_upgrade.

Here is what that looks like when you ask. Each numbered control point is one of the tools above, with the arguments the front page's own route table sends:

A topographic field map of the stack. Three questions are plotted from 'your app' through the ADVISOR advising office to the project that answers. 'Which PHP can I build on?' goes through policy_lookup (component: php) to CREED's policy.json. 'Which security headers do I need?' goes through list_stack_rules (chapter: runtime-and-headers) and read_project_docs (project: helmet) to HELMET. 'How do I get off PHP 8.2?' goes through the plan_upgrade prompt, policy_lookup, run_proctor_check and read_project_docs (project: booster) to Booster. Ask the map: three questions, three routes. Every control point is a real ADVISOR tool or prompt, and the whole trip is read-only.
Phone-sized field notes: the front page's ask box, legend and directions
Three phone cuts of the front page: 'Ask the map', with the question box set to 'Which PHP can I build on?' and a row of sample questions; the Legend, listing the read-only tools list_projects, get_project_status and read_project_docs; and Directions, three turns from composer require to a working client config.

Everything ADVISOR returns is labeled as reference data. PROCTOR in CI, not ADVISOR, decides pass or fail.

Configuration

ADVISOR reads the process environment only, never a file. The placeholders are in .env.example.

Variable Default Meaning
ADVISOR_ENABLED off Must be 1 or true, or the server refuses to start. advisor install sets it in the client config.
ADVISOR_ENV APP_ENV, then local production or prod always refuses to start.
ADVISOR_PROJECT_ROOT the working directory The folder run_proctor_check may look inside. Paths outside it are refused.
ADVISOR_READ_ONLY on Set to 0 or false to allow tools that write. None exist in 0.1. Read-only wins over ADVISOR_GROUPS.
ADVISOR_GROUPS all Comma list of tool groups to offer (stack, proctor, booster). See below for what each group may start.
ADVISOR_PROCTOR_TIMEOUT 120 Seconds before a PROCTOR run is stopped (1 to 900).
ADVISOR_BOOSTER_TIMEOUT 60 Seconds before a Booster plan is stopped (1 to 900). A plan is local and fast, so the default is shorter than a PROCTOR run.
ADVISOR_BOOSTER_BIN none Where upgrade_path finds Booster when the app has no vendor/bin/booster of its own: the path to booster's bin/booster (or a booster.phar). The app's own vendor/bin/booster always wins.
ADVISOR_MAX_CHARS 20000 Largest piece of text one doc call returns (1000 to 45000).
ADVISOR_AUDIT_LOG off A file for a one-line-per-call audit log: time, tool, a hash of the arguments, outcome, duration. Arguments are hashed, never written.
ADVISOR_LOG_LEVEL warning Log level on stderr (debug to emergency).
ADVISOR_STACK_DIR none Folder holding the sibling stack repos; used only by content:generate.
ADVISOR_PRIVATE_DENYLIST none A file (kept outside the repo) with private strings to strip from the bundle; used by content:generate and the public-posture test. See "Releasing".
ADVISOR_MODULES_FILE none An extra module manifest (see "Modules").

A bad value stops the server with a message on stderr. It does not guess.

Commands

php vendor/bin/advisor mcp                          # serve over stdio (your client starts this)
php vendor/bin/advisor install [--client=claude] [--write] [--force] [--path=.]
php vendor/bin/advisor content:verify               # check the bundled content against its manifest
php vendor/bin/advisor content:generate [--sources=<dir>] [--check]
php vendor/bin/advisor stack-parts [--write=<readme>] [--check=<readme>]
php vendor/bin/advisor doctor [--json]              # check the install when the server does not show up

Stdout carries only protocol messages. Logs, warnings and stray output go to stderr, so a client never sees garbage.

When it doesn't show up

You added the config, opened the project, and the advisor server is not in the list. Run:

php vendor/bin/advisor doctor

It checks the four things that keep a server from appearing, in plain words, and changes nothing:

  • php: the PHP on your machine satisfies ADVISOR's own composer.json (8.3 or newer).
  • content: the bundled data/ still matches its manifest.
  • client:claude, client:warriorgpt, client:cursor, client:vscode: each client's MCP config: is the file there, does it have the advisor entry, and is the script it points at in the project? A missing file is a warning, not a failure; you only need the one client you use.
  • mcp: the server actually starts. Doctor boots it in-process and asks for its tools.

A fail is something to fix; a warn is something you may not care about. The exit code is 0 when nothing failed and 1 when something did; --json prints the findings as JSON.

The advisor will see you now.

Served content

The handbook, policy, project docs, the WayneUI markup contract and WayneUI's 1.x to 2.x migration guide in data/ are generated from the sibling stack repositories by content:generate and verified at start-up against data/manifest.json (a SHA-256 for every file). If a file does not match, the server refuses to start rather than serve it. Files are cleaned on the way in: line endings are normalized and invisible characters (the TAG block, zero-width and bidirectional controls) are stripped. Each project entry also carries its version when the project publishes one (composer.json, else package.json, else the newest CHANGELOG heading).

Beside the generated docs, hand-written guides are kept by hand in generator/guides/ (one Markdown file per slug), the same way the ownership table is kept. Each is bundled into data/guides/ and served as advisor://guide/<slug>; the first is "Connect to Oracle on Citadel".

To refresh it, with the stack repos checked out side by side:

php vendor/bin/advisor content:generate --sources=/path/to/stack
php vendor/bin/advisor content:generate --sources=/path/to/stack --check   # exits 1 on drift

CI cannot see the sibling repositories, so composer ci runs content:verify, which needs none of them.

Releasing

ADVISOR is a public repository, so the bundle must not carry internal names. The public-posture test always checks generic shapes (ADR numbers, open-question numbers, design-doc paths, the coordination repo). Private strings (hostnames, people) are loaded from the file named by ADVISOR_PRIVATE_DENYLIST and checked only when the file is present.

To release:

  1. Set ADVISOR_PRIVATE_DENYLIST to a file kept outside the repository (one literal or regex: pattern per line, # comments).
  2. In GitLab CI, the file comes from a masked file-type CI variable.
  3. Regenerate the bundle with the file present: php vendor/bin/advisor content:generate --sources=/path/to/stack.
  4. Run composer ci to confirm the public-posture test passes.

The file is never committed. The bundle is regenerated with the file present before every release.

Modules

Each stack project can later ship its own ADVISOR tools. Modules load only from a manifest (modules.json), only from the Waynestate\ namespace, and only if they implement the Module interface. Nothing scans a folder.

Running the checks

Maintainers: how to build, test and release this project, and where its data comes from, is in MAINTAINING.md.

composer ci

That runs composer validate --strict, content:verify, PHPUnit, Pint, PHPStan (level 8, Pinstripe's raw preset, included from vendor/waynestate/pinstripe) and composer audit. No PHP on your machine? Use Docker:

docker run --rm -v "${PWD}:/app" -w /app composer:2.10.3 sh -c "composer install --no-interaction && composer ci"

Tests drive the real SDK server in-process with a small MCP client, snapshot tools/list, and start bin/advisor mcp as a subprocess to prove stdout stays clean. To accept an intended change to the tool list, run ADVISOR_UPDATE_SNAPSHOTS=1 vendor/bin/phpunit, then review and commit the diff.

Safety, in short

  • Off unless enabled; refuses production; refuses to start on a bad setting or a content file that fails its hash.
  • Read-only by default; no tool takes a command, a URL or a free path.
  • Every result is cleaned of invisible characters and labeled as data; secrets in PROCTOR output are redacted.
  • run_proctor_check runs one fixed program with an argument array and an allowlisted environment, never a shell.
  • upgrade_path runs Booster's read-only plan the same way: one fixed program, an argument array, an allowlisted command, never a shell. It plans; it never runs a hop.
  • No network calls, and no model calls, from ADVISOR itself.

See BEST_PRACTICES.md, and OPEN_QUESTIONS.md for what is decided, assumed and not yet built.

Why "ADVISOR"

Because registration is open, the advisor will see you now, and unlike the real one it knows which PHP version you are allowed to be on. A little Creed energy too: it will tell you who you are, in composer.json, whether you like it or not.

The brand board: the mark, lockups, palette and type
ADVISOR's brand board: the speech-bubble-and-compass mark on a Wayne State green tile, the app icon, horizontal and stacked lockups reading 'What applies, and what's next.', the mark on light and dark, the palette of green, gold, cream and a maroon site accent, Montserrat and Inter type, favicons at 64, 32 and 16 px, clear space, do and don't, and a chat-client mockup.

License

MIT. Copyright Wayne State University.

Everyone on the sheet
WayneUI and the stack. ADVISOR is the one with office hours. WayneUI CREED PROCTOR SESAME HELMET Sourdough Squire Preflight Pinstripe Booster Rollcall Drawbridge ADVISOR WELD Images are regenerated from the front page by scripts/readme-art. No appointment necessary.