Skip to content

Requirements

REQ-AUTH-001: URL-safe Base64 Token Decoding

Section titled “REQ-AUTH-001: URL-safe Base64 Token Decoding”

The Worker must extract the Bearer token from the Authorization header, decode it from URL-safe Base64 (RFC 4648 §5), and use the decoded value as a GitHub Personal Access Token for all GitHub Contents API calls.

If the Authorization header is absent or does not contain a Bearer token, the Worker must return HTTP 401 before dispatching any MCP tool call.

If the Bearer token value cannot be decoded as valid URL-safe Base64, the Worker must return HTTP 401.

After successful Base64 decoding, the Worker must verify that the decoded value matches a recognized GitHub PAT prefix (ghp_, github_pat_, or gho_). If it does not, the Worker must return HTTP 401. This catches misconfigured tokens early, before making a GitHub API call.

GitHub response codes 401, 403, and 404 must propagate to the caller as MCP error responses with the corresponding error codes (UNAUTHORIZED, FORBIDDEN, NOT_FOUND).


All repository, path, and branch configuration must be set via Cloudflare Worker environment variables at deploy time. There are no per-client overrides or initializationOptions.

Skills/agents and documentation must be configurable to target different repositories, branches, and paths independently.


REQ-SKILL-001: list_skills Returns Bundled Index

Section titled “REQ-SKILL-001: list_skills Returns Bundled Index”

list_skills must return a JSON array of skill entries from a bundled index. Each entry includes: name, description, argumentHint, userInvocable, and files (companion file manifest). No GitHub API calls are made at runtime.

get_skill must fetch {skillsPath}/{name}/SKILL.md from the configured repository and branch via the GitHub Contents API. The response must include name, content (decoded plain text), path, and sha.

get_skill responses must be cached for 10 minutes. When skipCache is true, the cache must be bypassed and refreshed with the new response.

REQ-SKILL-004: get_skill_file Fetches Arbitrary Files

Section titled “REQ-SKILL-004: get_skill_file Fetches Arbitrary Files”

get_skill_file must fetch {skillsPath}/{skill}/{file} from the configured repository. Content must be returned as-is from GitHub (Base64-encoded) with encoding: "base64" and size in the response.

Same caching behavior as get_skill (10-minute TTL, skipCache bypass).


REQ-AGENT-001: list_agents Returns Bundled Index

Section titled “REQ-AGENT-001: list_agents Returns Bundled Index”

list_agents must return a JSON array of agent entries from a bundled index. Each entry includes: name, description, model, and allowedTools. No GitHub API calls are made at runtime.

REQ-AGENT-002: get_agent Fetches Agent Profile

Section titled “REQ-AGENT-002: get_agent Fetches Agent Profile”

get_agent must fetch {agentsPath}/{name}.md from the configured repository and branch. The response must include name, content (decoded plain text), path, and sha.

Same caching behavior as get_skill (10-minute TTL, skipCache bypass).


REQ-DOC-001: list_docs Returns Bundled Index

Section titled “REQ-DOC-001: list_docs Returns Bundled Index”

list_docs must return a hierarchical JSON structure from a bundled index. Leaf values are page descriptions; intermediate keys are section names. No GitHub API calls are made at runtime.

REQ-DOC-002: get_doc Path Resolution with Fallback

Section titled “REQ-DOC-002: get_doc Path Resolution with Fallback”

get_doc must resolve the path array using the index.md convention:

  1. First try {docsContentPath}/{path.join('/')}/index.md
  2. If GitHub returns 404, fall back to {docsContentPath}/{path.join('/')}.md
  3. If both return 404, return a NOT_FOUND error.

get_doc must decode the Base64 content from GitHub and return it as plain text markdown. The response must include path, content, filePath, and sha.

Same caching behavior as get_skill (10-minute TTL, skipCache bypass).


All get_* tools that accept path parameters (name, skill, file, path[] segments) must reject values containing .., values starting with /, and values containing \. Rejected inputs must return an INVALID_PATH error.

The Worker must not store any secrets (tokens, keys) in environment variables, KV, or Durable Object state. The GitHub PAT is transient — present only in the request header for the duration of the tool call.


All errors must follow the error response shape: { error: { code, message, details } }. Details must include repo, path, branch, and githubStatus where applicable.

GitHub StatusMCP Error Code
401UNAUTHORIZED
403FORBIDDEN
404NOT_FOUND
Other non-2xxUPSTREAM_ERROR
N/A (validation)INVALID_PATH

REQ-BUILD-001: Index Generation from Source Repos

Section titled “REQ-BUILD-001: Index Generation from Source Repos”

The CI pipeline must clone both source repositories and generate three index files (skills-index.json, agents-index.json, docs-index.json) from frontmatter using js-yaml.

REQ-BUILD-002: Graceful Frontmatter Fallback

Section titled “REQ-BUILD-002: Graceful Frontmatter Fallback”

If a skill or agent file has no YAML frontmatter, the index entry must use the filename as name and null as description. The build must not fail.

The skills index must include a files array listing all files in the skill directory excluding SKILL.md, using relative paths.

REQ-BUILD-004: Docs Index Includes .md and .mdx

Section titled “REQ-BUILD-004: Docs Index Includes .md and .mdx”

The docs index generation must process both .md and .mdx files.

The build-and-deploy pipeline must run on: (1) push to main, (2) weekly cron (Saturday 00:00 Pacific / 07:00 UTC), (3) workflow_dispatch.

Generated index files must be importable as static JSON modules in the Worker source and embedded in the Worker bundle at deploy time.


REQ-INFRA-001: Cloudflare Workers Deployment

Section titled “REQ-INFRA-001: Cloudflare Workers Deployment”

The server must deploy as a Cloudflare Worker using wrangler deploy. The wrangler.toml must configure compatibility_date = "2025-06-01" and nodejs_compat.

The Worker must use Cloudflare’s McpAgent from the agents npm package for MCP HTTP+SSE protocol handling.

After the first version reaches main, the repository must have branch protection rules equivalent to the Arda-cards/hypothesis-mcp example repository.