Skip to content

RegionallyFamous/model-context-polytechnic

Repository files navigation

Model Context Polytechnic

Model Context Polytechnic is a WordPress plugin that exposes a public Model Context Protocol learning server over HTTP. WordPress supplies the runtime, REST routing, rewrite alias, database lifecycle, and plugin activation hooks.

The conceit is simple: WordPress is the campus, WordPress Plugin Craft is the flagship course of study, and the LLM is the student learning to build plugins with fewer heroic guesses and better code judgment.

The public campus lives at joinmcpoly.com. The flagship course endpoint is:

https://joinmcpoly.com/mcp/wordpress-plugin-craft

Self-hosted installs use the same paths on their own WordPress domain.

MCP Spec Alignment

This plugin targets the current MCP 2025-11-25 shape through wordpress/mcp-adapter and wordpress/php-mcp-schema.

  • The server exposes MCP tools, resources, and prompts.
  • The initialize response includes server instructions, capabilities, and protocol negotiation.
  • Tools use explicit input and output JSON schemas.
  • Resources include MCP metadata such as mcp.uri and MIME type.
  • Learner operations are public; optional authoring operations are hidden from the default MCP surface and protected at the ability permission layer when a host site enables them.

Institutional Voice

Model Context Polytechnic should sound like a venerable technical school, not a SaaS dashboard.

  • Voice: venerable, precise, warmly professorial, lightly witty, never corporate.
  • Metaphor: WordPress is the campus; WordPress Plugin Craft is the course of study; abilities are coursework; setup is enrollment and syllabus design; the learner is the LLM.
  • Style: make setup feel a little ceremonial, but keep technical instructions exact and plain.
  • Avoid: startup hype, fake Latin, generic AI-school vagueness, and jokes that slow down the work.

The same voice guidance is exposed to MCP clients through initialize instructions and the model-context-polytechnic/voice-guide resource.

Learning Model

The plugin does not train model weights. It schools the active AI session by giving it structured context, exercises, rubric feedback, anonymous enrollment, and retrievable learning memory.

Each published course can include:

  • Modules: syllabus sections.
  • Lessons: instructional material and objectives.
  • Exercises: prompts the AI can attempt.
  • Rubrics: deterministic criteria for feedback and pass/fail scoring.
  • Model answers: spoiler-safe exemplars the AI can request after an attempt for calibration and revision.
  • Progress: anonymous attempt history keyed by an enrollment_key.
  • Improvement signals: privacy-safe tool telemetry plus anonymous learner feedback, so the course can see what is confusing, helpful, brittle, or missing an example.

Public course endpoints expose learning tools without login. The LLM should call begin-course first; the server returns an anonymous enrollment_key, exact MCP-ready tool names, an autopilot runbook, an exact autopilot tool call, a verbose learning_status.story_script, and a campus_scene tool call. After the user asks to enroll or take the course, the model should continue through course packets without asking for permission between lessons. It should narrate campus_story.read_aloud or learning_status.story_script.read_aloud so the human can picture the Agent arriving at school, attending lecture, working in labs, receiving faculty notes, and graduating. It should call get-campus-scene, render the returned display_markdown or show image_url, and avoid text-art status boards. Clients that visibly render raw MCP image content blocks can additionally call get-campus-scene-image. Attempts without a key still work and automatically issue one unless remember=false. Treat enrollment_key as a lightweight enrollment card, not a WordPress password. After graduation, the Agent is asked to deliver graduation_speech, tell everyone what it learned, report confidence, reflect on how WordPress Plugin Craft will improve its future WordPress plugin work, and submit that reflection through the learner feedback path.

Repeated exercise calls can choose their verbosity. Use response_mode=student_theater for the full campus narration, images, and story fields. Use response_mode=gradebook when the client wants compact scoring, matched terms, missing terms, and next tool calls. Exercises expose attempt_preflight.required_exact_vocabulary, rubric_vocabulary.required_terms, and rubric_vocabulary.accepted_aliases so the model sees important WordPress terms before attempting instead of discovering them only after grading.

Progress fields use explicit units: completion_percent is 0-100, while completion_ratio is 0-1. Exercise attempts also separate this_attempt_result from global_next_unpassed_work, because an individual passed attempt can still leave an earlier exercise elsewhere in the course unfinished.

The MCP HTTP adapter stores protocol sessions against a WordPress user. To keep public learning genuinely no-login, the plugin creates a plugin-owned anonymous subscriber used only for public MCP session IDs and briefly serializes public session requests to avoid user-meta races. That internal user is not a learner account, cannot authorize private write tools, and is removed on uninstall.

The public registrar is LLM-first. If a model is unsure what to do, it should call model-context-polytechnic-orient or read the model-context-polytechnic/llm-interface resource. Course responses prefer stable handles, MCP-ready next_actions, tool_calls, and explicit recovery notes so the model does not have to infer workflow from a loose tool list.

server-status includes a public health object with adapter availability, endpoint URLs, and a small route-registration smoke check. If /wp-json/ or /mcp ever returns a WordPress critical error, check PHP fatal logs first and run composer release:check before shipping the next ZIP.

The bundled flagship course is WordPress Plugin Craft. It is seeded automatically on activation and updated idempotently when the bundled course-pack fingerprint changes. Learner attempts and enrollment memory are not deleted by reseeding.

Bundled courses live in course-packs/{course-slug}/ instead of large PHP arrays:

course-packs/wordpress-plugin-craft/
├── course.json
├── sources.json
├── lessons/*.md
├── exercises/*.json
└── references/*.md

course.json defines metadata, modules, lesson ordering, exercise file references, and public reference files. Lessons are Markdown so they can be edited and reviewed like curriculum. Exercises are JSON so rubrics, required terms, hints, and expected output schemas remain machine-checkable. sources.json is the source bibliography used to seed the public bibliography resource.

Tradeoff-heavy exercises can include model_answer exemplars with the expected summary, work, and checks fields plus calibration notes. Normal get-exercise calls do not reveal the model answer; learners request it with include_model_answer=true after attempting or when revising a failed answer.

The course-pack loader validates packs before seeding. A malformed pack will not be silently converted into a half-course. Bundled courses are reseeded from a content fingerprint, so edits to Markdown lessons, JSON exercises, references, or bibliography files are picked up without hand-bumping a PHP array version.

Validate course packs locally with:

composer course-packs:validate

The validator checks required metadata, duplicate slugs, readable in-pack file paths, JSON validity, lesson/exercise references, rubric criteria, deterministic grading terms, and bibliography URLs.

The repository also includes reference schemas for course-pack authors:

schemas/course-pack.schema.json
schemas/exercise.schema.json

The built-in validator is the enforcement path used by the plugin; the schemas are there so editors and external tooling can catch mistakes before the registrar sees them.

Run the local foundation check before packaging:

composer foundation:check

That check runs PHP syntax checks for non-vendor plugin files, parses non-vendor JSON, validates course packs, and confirms Jetpack Autoloader output exists.

You can also simulate the first course flow without a WordPress runtime:

composer course-flow:simulate

For repeated LLM-student review, run the Course Lab:

composer course-lab
composer cohort-lab
composer extended-cohort-lab
composer stress-lab
php bin/course-lab.php --students=10
php bin/course-lab.php --students=20
php bin/course-lab.php --agent-brief

The lab checks public enrollment, stable handles, practice density, exercise schemas, feedback loops, and course-improvement signals. It also runs deterministic student cohorts across orientation, memory, security, storage, blocks, performance, release, course-authoring, LLM-interface, capstone-maintainer, privacy, admin UX, PHP architecture, testing, hooks, diagnostics, review cadence, namespace safety, lifecycle, and remote-service lenses. The stress lab adds fixture-driven friction scenarios plus golden weak/strong exam answers scored against real rubrics. Use the cohort report first; use stress scenarios for regressions; use the agent brief for larger read-only parallel review; then fold repeated findings back into course-pack files.

To prove the same loop over the real MCP HTTP transport on a WordPress site, run:

composer http-course-smoke -- --url=https://joinmcpoly.com/mcp/wordpress-plugin-craft
composer http-course-completion-smoke -- --url=https://joinmcpoly.com/mcp/wordpress-plugin-craft

The smoke tests post MCP JSON-RPC requests to prove first-day enrollment, exercise attempts, memory retrieval, certificate readiness, and full-course certificate issuance. Browser GET requests to MCP endpoints may return 405 Method Not Allowed; the transport is POST-based. See http-smoke.md.

Requirements

  • WordPress 6.9+
  • PHP 8.1+
  • Composer

Install

cd /path/to/wp-content/plugins/model-context-polytechnic
composer install

Activate the plugin in WordPress, then flush rewrite rules by saving Settings > Permalinks.

Deactivation keeps courses, enrollments, attempts, and tokens. Uninstall removes plugin-owned tables, schema options, and rate-limit transients.

WordPress Site Themelet

The public admissions site is the WordPress themelet in themelet/model-context-polytechnic-themelet/. joinmcpoly.com is the canonical website; the old GitHub Pages deployment is no longer published.

Install that folder into wp-content/themes/ or package it as a ZIP, for example dist/model-context-polytechnic-themelet-1.0.15.zip, if you want a WordPress site to look like the Model Context Polytechnic campus.

The themelet is intentionally separate from the MCP plugin. WordPress sees a normal theme with style.css, functions.php, index.php, local assets, enqueued site.css/site.js, wp_head(), and wp_footer(), but the page is essentially a focused static admissions site. It includes favicon files, a web app manifest, a generated Open Graph image, canonical metadata, social card tags, JSON-LD, and a robots.txt sitemap hint. The plugin release ZIP does not include the themelet; ship or activate it separately.

Release

Before packaging a distributable build, run the same gates that CI uses:

composer install --no-dev --optimize-autoloader
composer lint
composer test
composer release:check

Build the installable ZIP and checksum locally with:

composer version:bump -- --version=1.0.15
composer release:build -- --version=1.0.15

The version bump script updates the plugin header, MODEL_CONTEXT_POLYTECHNIC_VERSION, Server::SERVER_VERSION, and themelet header/constants. The release builder creates both dist/model-context-polytechnic-1.0.15.zip and dist/model-context-polytechnic-themelet-1.0.15.zip with correct top-level install folders. The plugin ZIP includes assets/, vendor/, course-packs/, schemas/, includes/, the bootstrap file, README.md, CHANGELOG.md, composer.json, composer.lock, and uninstall.php; local labs, docs, tests, temporary files, and GitHub workflow files are left out of the install artifact.

Publishing a stable release is tag-driven:

git tag v1.0.15
git push origin v1.0.15

The GitHub Actions release workflow reruns composer release:check, builds the ZIP, writes a .sha256 checksum, and attaches both files to the GitHub release. See release-checklist.md for the complete release and smoke-test checklist.

Authentication

Learner MCP calls are public. The normal course path at https://joinmcpoly.com/mcp/wordpress-plugin-craft does not require a login, password, WordPress account, or setup.

Private operator data is different. To let Codex or another operator client read the private feedback digest and course stats without WP-CLI, add one long secret to wp-config.php:

define( 'MODEL_CONTEXT_POLYTECHNIC_OPERATOR_TOKEN', 'replace-with-a-long-random-operator-secret' );

Then connect the operator MCP client to the same course endpoint with a bearer header:

{
  "mcpServers": {
    "mcpoly-feedback": {
      "url": "https://joinmcpoly.com/mcp/wordpress-plugin-craft",
      "headers": {
        "Authorization": "Bearer replace-with-a-long-random-operator-secret"
      }
    }
  }
}

Ask the client to call:

model-context-polytechnic-wordpress-plugin-craft-get-feedback-digest
model-context-polytechnic-wordpress-plugin-craft-get-course-stats

The digest tool returns raw learner feedback, graduation reflections, aggregate signals, and recommendations. The stats tool returns private counts for enrollments, attempts, completion-eligible learners, certificates issued, feedback volume, and recent activity. The operator token is not an enrollment key, not a WordPress login, and not a public course password; it only opens the protected registrar drawer. If the server strips Authorization, forward it at the host or web-server layer before debugging the plugin.

For a safer config file, store only the SHA-256 hash instead of the plaintext operator token:

define( 'MODEL_CONTEXT_POLYTECHNIC_OPERATOR_TOKEN_HASH', 'sha256-hash-of-the-operator-secret' );

Optional write-capable authoring abilities remain hidden by default; if a host site enables them, they still require a separate bearer token or a WordPress user with the configured capability. WP-CLI can mint those write tokens, but it is not required for private operator digests or stats:

wp model-context-polytechnic token mint --email=user@example.com --label=claude-desktop

Or mint a token and print ready-to-paste MCP client config in one command:

wp model-context-polytechnic auth config --client=claude --transport=proxy --label=claude-desktop

Options:

wp model-context-polytechnic auth config --access=read --client=generic --transport=direct
wp model-context-polytechnic auth config --access=write --client=cursor --transport=proxy --site-url=https://joinmcpoly.com

The plugin also has a public model-context-polytechnic-client-config tool. Pass course_slug to generate a config for a published course endpoint instead of the private registrar endpoint.

The plaintext write token is shown once. Store only the plaintext token in the MCP client config; the plugin stores only a SHA-256 hash.

Useful token commands:

wp model-context-polytechnic token list
wp model-context-polytechnic token revoke --id=123
wp model-context-polytechnic token revoke --token=mcpoly_plaintext_token

Write tools can also authorize a normal WordPress user request. For LLM/MCP clients, use a WordPress Application Password rather than the account's main password. Application Passwords are a WordPress core REST API authentication method and can be revoked independently from the user's login password.

MCP Endpoint

For read-only clients that support HTTP MCP, use the vanity endpoint directly without headers:

{
  "mcpServers": {
    "model-context-polytechnic": {
      "url": "https://joinmcpoly.com/mcp/wordpress-plugin-craft"
    }
  }
}

For the public registrar rather than the flagship course, use https://joinmcpoly.com/mcp.

For clients that need to call write tools on a self-hosted install, include the bearer header:

{
  "mcpServers": {
    "model-context-polytechnic": {
      "url": "https://joinmcpoly.com/mcp",
      "headers": {
        "Authorization": "Bearer mcpoly_replace_with_token_from_wp_cli"
      }
    }
  }
}

Alternatively, write tools can use a WordPress Application Password. Direct HTTP clients need a Basic auth header containing base64(username:application_password):

{
  "mcpServers": {
    "model-context-polytechnic": {
      "url": "https://joinmcpoly.com/mcp",
      "headers": {
        "Authorization": "Basic base64(wordpress_username:application_password_from_user_profile)"
      }
    }
  }
}

For read-only clients that expect a local command, use Automattic's current remote proxy:

{
  "mcpServers": {
    "model-context-polytechnic": {
      "command": "npx",
      "args": ["-y", "@automattic/mcp-wordpress-remote@latest"],
      "env": {
        "WP_API_URL": "https://joinmcpoly.com/mcp/wordpress-plugin-craft",
        "OAUTH_ENABLED": "false"
      }
    }
  }
}

For write-enabled proxy clients, pass the bearer header through CUSTOM_HEADERS:

{
  "mcpServers": {
    "model-context-polytechnic": {
      "command": "npx",
      "args": ["-y", "@automattic/mcp-wordpress-remote@latest"],
      "env": {
        "WP_API_URL": "https://joinmcpoly.com/mcp",
        "OAUTH_ENABLED": "false",
        "CUSTOM_HEADERS": "{\"Authorization\":\"Bearer mcpoly_replace_with_token_from_wp_cli\"}"
      }
    }
  }
}

For write-enabled proxy clients using a WordPress Application Password, pass the WordPress username and application password through the proxy environment:

{
  "mcpServers": {
    "model-context-polytechnic": {
      "command": "npx",
      "args": ["-y", "@automattic/mcp-wordpress-remote@latest"],
      "env": {
        "WP_API_URL": "https://joinmcpoly.com/mcp",
        "OAUTH_ENABLED": "false",
        "WP_API_USERNAME": "wordpress_username",
        "WP_API_PASSWORD": "application_password_from_user_profile"
      }
    }
  }
}

The canonical REST endpoint also works:

https://joinmcpoly.com/wp-json/model_context_polytechnic/mcp

Course Registry

Model Context Polytechnic can host many public MCP servers from one WordPress install. Each saved server is a course.

The plugin ships with a published course:

https://joinmcpoly.com/mcp/wordpress-plugin-craft
https://joinmcpoly.com/wp-json/model_context_polytechnic/courses/wordpress-plugin-craft

WordPress Plugin Craft covers plugin lifecycle, architecture, hooks, security, storage, REST APIs, admin UX, JavaScript and blocks, performance, testing, distribution, and advanced PHP/JavaScript judgment.

The main /mcp server is the public registrar. By default it lists catalog and diagnostic abilities only; it does not advertise course-authoring tools to public MCP clients.

Host sites can opt into the legacy authoring surface with the model_context_polytechnic_authoring_tools_enabled filter. When enabled, these private tools still require Auth::require_write_access:

  • model-context-polytechnic/create-course
  • model-context-polytechnic/update-course
  • model-context-polytechnic/add-module
  • model-context-polytechnic/add-lesson
  • model-context-polytechnic/add-exercise
  • model-context-polytechnic/set-rubric
  • model-context-polytechnic/describe-syllabus
  • model-context-polytechnic/add-ability
  • model-context-polytechnic/add-content
  • model-context-polytechnic/publish-course
  • model-context-polytechnic/describe-course

Published courses get their own public endpoint:

https://joinmcpoly.com/mcp/{course-slug}
https://joinmcpoly.com/wp-json/model_context_polytechnic/courses/{course-slug}

Public users connect to the course endpoint without logging in. Course setup is not part of the default public learner flow.

If the plugin is already active when new storage code is added, the auth, registry, and learning tables are installed automatically on the next WordPress init request. Re-saving Settings > Permalinks still flushes the /mcp/{course-slug} rewrite alias.

Course servers and their ability lists are assembled when the MCP server is registered for a request. After a host site changes bundled or database-backed coursework, reconnect or refresh the MCP client to see the new endpoint/tool list.

Published course endpoints automatically include these learning tools. WordPress ability IDs allow one namespace slash, so course handles are folded into the ability name. All are public learner tools except the private operator tools, which require an operator bearer token:

  • model-context-polytechnic/{course-slug}-begin-course
  • model-context-polytechnic/{course-slug}-take-course
  • model-context-polytechnic/{course-slug}-get-study-plan
  • model-context-polytechnic/{course-slug}-search-course
  • model-context-polytechnic/{course-slug}-get-syllabus
  • model-context-polytechnic/{course-slug}-get-lesson
  • model-context-polytechnic/{course-slug}-get-exercise
  • model-context-polytechnic/{course-slug}-attempt-exercise
  • model-context-polytechnic/{course-slug}-get-next-work
  • model-context-polytechnic/{course-slug}-get-progress
  • model-context-polytechnic/{course-slug}-get-campus-scene
  • model-context-polytechnic/{course-slug}-get-campus-scene-image
  • model-context-polytechnic/{course-slug}-get-learning-memory
  • model-context-polytechnic/{course-slug}-get-certificate
  • model-context-polytechnic/{course-slug}-submit-feedback
  • model-context-polytechnic/{course-slug}-get-course-improvement-signals
  • model-context-polytechnic/{course-slug}-get-course-stats (private operator token required)
  • model-context-polytechnic/{course-slug}-get-feedback-digest (private operator token required)

MCP clients see sanitized tool names with the slash converted to a dash, such as model-context-polytechnic-wordpress-plugin-craft-begin-course and model-context-polytechnic-wordpress-plugin-craft-take-course. Tool suggestions returned inside tool_calls, next_actions, and next_tool already use the MCP-ready dashed names.

The public learning flow is intentionally light:

  1. Connect an MCP client to https://joinmcpoly.com/mcp/{course-slug}.
  2. Call begin-course.
  3. Keep the returned enrollment_key in the conversation, client notes, or project memory.
  4. Call the exact tool name returned in tool_calls[0].tool or tool_resolution.tools["take-course"] with mode=full_course to receive the remaining lessons and exercises as an autopilot packet.
  5. Do not print text-art status boards. Use learning_status.story_script.read_aloud for verbose campus narration, call get-campus-scene, and render its display_markdown or show its image_url so the human sees the campus postcard.
  6. Study the packet, attempt the included exercises with enrollment_key, revise failed work, and keep following returned tool_calls without asking the user to advance lesson by lesson.
  7. Use response_mode=gradebook on repeated attempt-exercise calls when you want compact scorebook output instead of full campus narration.
  8. Read attempt_preflight.required_exact_vocabulary, rubric_vocabulary.required_terms, and accepted aliases before attempting so conceptually correct answers include the WordPress vocabulary the deterministic grader expects.
  9. Use module_batch plus next_cursor only when the client needs smaller packets.
  10. Use get-study-plan when you have a goal and want a route through the course.
  11. Use get-next-work to check the next incomplete exercise or completion state.
  12. Use search-course to retrieve targeted lessons, exercises, and references.
  13. Pass enrollment_key to attempt-exercise, get-progress, and get-learning-memory.
  14. When get-next-work reports complete=true, call get-certificate with the same enrollment_key.
  15. After get-certificate succeeds, do not call it again as the next step. Follow post_certificate_next_work: retrieve get-learning-memory, deliver the graduation speech, answer the reflection, and optionally submit that reflection as feedback.
  16. Optionally call get-campus-scene-image when the client visibly renders raw MCP image content blocks; get-campus-scene is the more reliable visible path because it returns a public HTTPS image URL and markdown snippet.
  17. After graduation, deliver graduation_speech first: tell everyone what the Agent learned, what habits changed, and what still needs human review.
  18. Reflect on confidence and how the course will improve future WordPress plugin work, then send that confidence/reflection note with submit-feedback.
  19. Call submit-feedback when a lesson, exercise, tool response, or next action is confusing, helpful, stale, or missing an example.
  20. Call get-course-improvement-signals before proposing course changes so recommendations are based on accumulated evidence.

The enrollment key is anonymous. The plugin stores only a SHA-256 hash of it. If an attempt is submitted without an enrollment key, attempt-exercise will evaluate the work, create a new enrollment key, store the attempt against it, and return the key so future calls can remember the work.

Completion is also anonymous. get-certificate issues or retrieves a certificate only after every published exercise has a passing attempt for that enrollment key. The certificate includes a deterministic certificate ID, verification code, completion statement, graduation_speech, and optional transcript. It proves completion for that anonymous learner record inside this WordPress-hosted MCP server; it is not a WordPress login, password, or human identity credential.

Public learning data is bounded. Exercise answers are capped at 20 KB, feedback comments are capped at 6 KB, public learning reads/writes are rate-limited, and old anonymous attempts, feedback, and telemetry events are pruned by a daily cleanup job. Certificate records store hashed enrollment identity plus completion metadata, not answers. The default retention window is 180 days and can be changed with the model_context_polytechnic_learning_retention_days filter.

Every public course tool call records a privacy-safe learning event: tool slug, target handle when known, result status, duration, and an input fingerprint. Enrollment keys are hashed and large fields such as answers or comments are hashed by fingerprint rather than stored in telemetry. This does not auto-edit the course; it creates aggregate improvement signals. The public get-course-improvement-signals tool returns counts, hotspots, exercise pass-rate patterns, and recommendations without returning raw feedback comments.

Raw learner feedback and small-cohort stats are private operator data. The recommended path is the same MCP course endpoint with an operator bearer token configured in wp-config.php, then the protected digest or stats tool:

{
  "mcpServers": {
    "mcpoly-feedback": {
      "url": "https://joinmcpoly.com/mcp/wordpress-plugin-craft",
      "headers": {
        "Authorization": "Bearer replace-with-a-long-random-operator-secret"
      }
    }
  }
}
{
  "window_days": 30,
  "limit": 20
}

Codex can use the public MCP endpoint for aggregate signals. To let Codex review raw comments, connect it with the operator bearer header and ask it to call model-context-polytechnic-wordpress-plugin-craft-get-feedback-digest. See codex-feedback.md.

To see course telemetry without raw comments, ask the operator-connected client to call model-context-polytechnic-wordpress-plugin-craft-get-course-stats with input such as:

{
  "window_days": 30,
  "daily_days": 14,
  "exercise_limit": 8
}

The stats response includes all-time and recent enrollments, attempts, completion-eligible learners, issued certificates, feedback counts, tool-call counts, daily activity, and exercise outcome summaries.

They also include a syllabus resource:

  • model-context-polytechnic/{course-slug}-resource-syllabus

Rubric criteria support deterministic grading with required_terms or any_terms:

{
  "criteria": [
    {
      "name": "Names the operating model",
      "points": 1,
      "required_terms": ["public read", "private write"]
    },
    {
      "name": "Uses institutional metaphor",
      "points": 1,
      "any_terms": ["syllabus", "registrar", "course"]
    }
  ]
}

The first registry implementation is intentionally no-code: saved abilities are static or templated tools/resources/prompts. Response templates support:

{{input}}
{{input.field_name}}
{{course.name}}
{{course.slug}}
{{ability.name}}
{{ability.slug}}

For tool responses, if the rendered template is valid JSON, it is returned as structured data. Otherwise it is returned as text with the original input.

Public Read Abilities

  • model-context-polytechnic/server-status
  • model-context-polytechnic/client-config
  • model-context-polytechnic/orient
  • model-context-polytechnic/connection-playbook
  • model-context-polytechnic/echo-schema
  • model-context-polytechnic/server-manifest
  • model-context-polytechnic/llm-interface
  • model-context-polytechnic/voice-guide
  • model-context-polytechnic/troubleshoot-connection
  • model-context-polytechnic/course-catalog

WordPress ability IDs use dashes because WordPress 6.9 validates ability names as lowercase alphanumeric, dash, and slash characters.

Private Write Tools

Write-capable abilities should use ModelContextPolytechnic\Mcp\Auth::require_write_access as their permission_callback. That accepts either a valid plugin bearer token or a WordPress-authenticated user with the configured capability. Ability callbacks can read the validated plugin token row from:

$GLOBALS['model_context_polytechnic_mcp_token']

Use that token id to scope records in custom tables when writes need per-client ownership or auditing.

Example write ability permission:

'permission_callback' => [ ModelContextPolytechnic\Mcp\Auth::class, 'require_write_access' ],

The default WordPress capability for Application Password-authenticated writes is edit_posts. Change it with the model_context_polytechnic_write_capability filter.

About

Model Context Polytechnic: a public MCP learning server for WordPress

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors