berbotu-mcp
Allows creating new demo files in the vault by committing to a GitHub repository via the GitHub API.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@berbotu-mcpWhat demos are in the listening stage?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
berbotu-mcp
An MCP server that lets an AI read and write real records in a live repository — without being able to break anything quietly.
It sits over the vault behind a small record label: releases, demos, and label state, all markdown with YAML frontmatter. Four tools over stdio. Three read, one writes.
"what demos came in this week I haven't decided on yet?" → list_demos { stage: "Listening" }
"what's the next release scheduled?" → list_releases { stage: "Scheduled", limit: 1 }
"log the demo that just came in from X" → add_demo ✍️ writes a real git commitWhy it's built the way it is
The interesting problem isn't connecting an AI to data. That's an afternoon. The problem is that an AI with write access is an intern who never asks twice — so every design decision here is about what happens when it's wrong.
Every write is its own git commit, through the GitHub Contents API.
Not a filesystem write. A commit. Which means every single thing the AI ever did is attributable, diffable, and
revertible with one command. If it writes garbage at 3am, I don't need a backup — I need git revert. This costs
an API round-trip per write and it's worth it.
Existence is SHA-checked before anything is touched.
getVaultFile resolves the file's SHA first. Passing a sha to the create endpoint turns a create into an
overwrite — so the check isn't defensive, it's the difference between "this demo already exists" and silently
destroying a record.
Inputs are validated at the boundary, then again in the handler.
Tool inputs are zod schemas — stage is an enum, so a hallucinated stage gets a clean rejection with the valid
options instead of writing nonsense. Then addDemo re-validates the same fields itself. The code calls this
defence in depth: the schema is the contract, but a future caller might not go through it.
Tools carry honest annotations.
readOnlyHint: false — it writes
destructiveHint: true — appends a commit to a real git repo
idempotentHint: false — calling twice with the same args creates two demosThese are hints to the model about what it can safely retry. add_demo is not idempotent and saying otherwise
would invite exactly the double-write it warns about.
Read-only first, writes later.
Stages 1–2 shipped with no write path at all. add_demo landed only once the read tools had been running against
the real vault long enough to trust the parsing. There was no deadline — that's just the order that made the
mistakes cheap.
Errors return, they don't throw.
Every tool returns isError: true with a human-readable reason — missing env var, missing folder, malformed
frontmatter, 401, 422, network down. An MCP server that throws gives the model a stack trace to hallucinate
around. One that explains gives it something to say to the user.
Related MCP server: git-mcp
The bug that justifies all of it
While building the data layer, list_releases returned 1 of 12 releases. No error. No warning. Just a
confident, wrong, almost-empty list.
The cause: gray-matter's default YAML engine treats a duplicate map key as a fatal parse error and returns
{} for the whole file. The vault had duplicate keys in real files — a separate script had been appending
ig_posted: true twice. Eleven records were being silently dropped on the floor.
Fix was the yaml package with { uniqueKeys: false } — lenient, last-duplicate-wins, parses all twelve.
The point isn't the fix. The point is that nothing failed. No exception, no red text. If I'd trusted the output, an AI would have been confidently telling me I had one release. That's the whole reason this repo is paranoid: the dangerous failures are the quiet ones.
Quick start
npm install
npm run build # TS → dist/
npm run inspect # MCP Inspector web UI, call the tools by handAttach to Claude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"berbotu": {
"command": "node",
"args": ["/path/to/berbotu-mcp/dist/index.js"],
"env": { "BERBOTU_VAULT_PATH": "/path/to/vault" }
}
}
}Read tools need BERBOTU_VAULT_PATH. add_demo also needs VAULT_WRITE_PAT — a fine-grained GitHub PAT scoped
to one repo with Contents: Read and write. See .env.example.
Tools
Tool | Args | Returns |
| none | version, vault path, pid, node — confirms it's alive and pointed at the right vault |
|
|
|
|
|
|
|
| creates a demo file as a GitHub commit |
Honest limits
stdio only. Local. HTTP transport + JWT auth was the next stage and hasn't been built — there was no reason to.
One writer. No conflict handling beyond the SHA existence check. Fine for one operator, wrong for a team.
Read tools are filesystem, writes are API. A deliberate split — reads want to be fast and local, writes want to be auditable. It does mean a write isn't visible to a read until the repo syncs.
Four tools. Small on purpose. Every tool with write access is a thing that can be wrong at 3am.
Stack
TypeScript · @modelcontextprotocol/sdk · zod · yaml · GitHub Contents API · stdio
Built AI-assisted. I'm not an engineer and I'm not trying to be — I'm someone who knows what to build and how to keep it from breaking things.
Available Tools
4 toolsadd_demoAdd a new demoADestructive
Creates a new demo entry in the Berbotu vault by committing a Markdown file to the berbotu/vault GitHub repo (path: 00 Releases/Demos/{ARTIST} - {TITLE}.md). Use this when the user wants to log a fresh submission — e.g. 'add a demo from RULACID called UNTITLED', or 'log a new demo from the email I just pasted'. REQUIRED: artist + track. Both must be non-empty strings. OPTIONAL: stage (default 'Listening'), received_date (default today UTC), notes (default empty). Refuses to overwrite if a demo with the same artist+title already exists — in that case the user should edit via admin.berbotu.com instead. On success returns the created file path, the full frontmatter that was written, and a permalink to the GitHub commit so the user can audit the change.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Free-text notes for the demo card — short context like 'sent via IG DM' or 'recommended by GADDAM'. | |
| stage | No | Initial stage. Defaults to 'Listening' (the inbox state). Other values flow: Listening → Review → Interested → Hold → Pass → Converted. | |
| track | Yes | Track title. Use 'UNTITLED' if the producer didn't name it. | |
| artist | Yes | Artist or producer alias. Use the same spelling/case the user provided — the vault convention is ALL CAPS but we do not force-uppercase here. For collabs use 'A & B' as a single string. | |
| received_date | No | Date the demo was received (YYYY-MM-DD, UTC). Defaults to today. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important side effects beyond the annotations: it commits a Markdown file to a GitHub repo, refuses to overwrite existing demos, and returns a GitHub commit permalink. This adds meaningful behavioral context, especially clarifying that the destructiveHint=true annotation does not imply overwriting existing data.
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 information-dense with no filler. Each sentence serves a distinct purpose: defining the action and repo path, giving use-case examples, listing requirements/defaults, explaining conflict handling, and describing return values.
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?
For a tool with 5 parameters and no output schema, the description covers all necessary context: trigger, constraints, defaults, conflict behavior, side effects, and return values. It fully prepares an agent to invoke the tool correctly and interpret the result.
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?
The input schema already provides 100% description coverage for all 5 parameters with detailed semantics, so the baseline is 3. The description mostly restates the required/optional fields and defaults, adding only the path formula (artist + title) but no substantially new parameter meaning.
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 uses a specific verb ('Creates'), a concrete resource ('Berbotu vault by committing a Markdown file'), and an exact repository path, making the tool's purpose unmistakable. It clearly distinguishes this tool from the sibling read/list tools (ping, list_demos, list_releases).
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 states when to use the tool: 'Use this when the user wants to log a fresh submission', with concrete examples. It also provides a when-not-to-use alternative: if a demo already exists, the user should edit via admin.berbotu.com instead, since this tool refuses to overwrite.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_demosList demosA
Lists demo submissions from the Berbotu vault, sorted newest-first by received_date. Each item has: artist, track title, status (stage), received date, and an optional 1-5 star score. Use this when the user asks about incoming submissions, the demo pipeline, A&R inbox, or anything like 'what demos have we got?'. Optional stage arg filters by stage substring (case-insensitive) — e.g. 'listening', 'interested', 'pass'.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of demos to return (1-200). Omit for no limit. | |
| stage | No | Substring of the demo stage to filter on, case-insensitive. Common values: 'Listening', 'Review', 'Interested', 'Hold', 'Pass', 'Converted'. Omit to return all demos. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses sorting order, the exact fields returned, and the case-insensitive substring filtering behavior for the stage argument. While no annotations are provided, this covers the most important behavioral traits for a read/list operation.
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?
Four concise, front-loaded sentences cover purpose, output fields, usage triggers, and a filter parameter without wasted words. Each sentence earns its place, making it easy to parse quickly.
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?
Since there is no output schema, the description correctly enumerates the item fields (artist, title, status, date, score), explains sorting, and gives usage scenarios. The schema already handles parameter details, so nothing essential is missing.
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?
The schema description coverage is 100%, so the baseline is 3. The description adds minor redundancy with examples ('listening', 'interested', 'pass') but does not meaningfully enhance understanding beyond the schema's existing parameter descriptions.
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 opening sentence specifies the exact function: 'Lists demo submissions from the Berbotu vault, sorted newest-first by received_date.' This includes a specific verb, resource, and sorting detail, clearly distinguishing it from siblings like list_releases and add_demo.
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?
It explicitly states when to use: 'Use this when the user asks about incoming submissions, the demo pipeline, A&R inbox, or anything like...' This provides strong contextual guidance, though it does not name alternatives or state when not to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_releasesList releasesA
Lists track + EP releases from the Berbotu vault, sorted newest-first by release_date. Each item has: title, artist, release date, status (stage), and EP/single flag. Use this when the user asks about the label catalog, scheduled releases, what's coming out, what shipped, or anything about 'releases'. Optional stage filter (substring, case-insensitive) — common: 'Released', 'Scheduled', 'DITTO', 'On Hold'.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of releases to return (1-200). | |
| stage | No | Substring of the release stage to filter on, case-insensitive. Common values: 'Released', 'Scheduled', 'DITTO Submitted', 'On Hold', 'Passed'. Omit for all stages. | |
| includeEps | No | Include EP releases (default true). Set false to list singles only. | |
| includeTracks | No | Include single-track releases (default true). Set false to list EPs only. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses sort order (newest-first by release_date), the fields returned, and the filter semantics (substring, case-insensitive). It omits explicit statement of read-only nature, but the 'List' verb implies it and no side effects are expected for a list operation.
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 three sentences long, front-loaded with the core purpose, followed by return fields and usage guidance. Every sentence serves a distinct function with no redundant filler.
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 usefully lists returned fields and order. All four parameters are fully documented in the schema, so the description doesn't need to repeat them. Minor gap: the 'track + EP' terminology is not reconciled with the schema's 'single-track releases', but this is a minor ambiguity.
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%, so baseline is 3. The description adds no substantive parameter meaning beyond the schema; it merely recounts the stage filter with slightly different common values. It does not mention limit, includeEps, or includeTracks, but the schema already documents these fully.
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 lists track + EP releases from the Berbotu vault, with a specific resource and scope. It distinguishes itself from sibling list_demos by focusing on releases, and the verb 'List' is specific.
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 gives explicit 'Use this when' triggers, including label catalog, scheduled releases, what's coming out, and 'anything about releases'. However, it does not explicitly mention when not to use it or compare to the sibling tool list_demos, so it falls short of full alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pingHealth checkA
Returns 'OK' plus server name, version, vault path, current timestamp, process id, and Node.js version. Use this to confirm the Berbotu MCP server is reachable and configured correctly.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It states the exact return fields and that the tool is a health check, which implies read-only behavior and no side effects. It does not cover error cases or response format, but for a ping tool this is adequate.
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 two sentences, front-loaded with the return value and purpose. Every word is functional with no redundancy or filler.
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 tool's simplicity (no params, no output schema, no annotations), the description adequately covers the purpose and return values. It does not specify response format or error scenarios, but those are minor gaps for a basic health check.
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?
The tool has zero parameters, so the baseline is 4. The description adds nothing about parameters because there are none, and no parameter explanation is needed.
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 returns 'OK' plus server metadata and explicitly identifies its purpose as confirming the MCP server is reachable. This specific verb + resource scope distinguishes it from sibling tools that list or add demos/releases.
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 says 'Use this to confirm the Berbotu MCP server is reachable and configured correctly', providing clear guidance on when to use it. However, it does not mention alternatives or when-not-to-use cases, so it falls short of the top score.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool has a clearly distinct purpose: ping for health check, list_demos for demo submissions, list_releases for catalog releases, and add_demo for creating new entries. No overlapping resource or action.
Tools follow a consistent verb_noun pattern with snake_case (list_demos, list_releases, add_demo). ping is a simple verb but is standard and does not disrupt the pattern.
Four tools is small but well-scoped for a niche vault/music label server. It covers health, listing, and creation, though could add more operations in the future.
The core workflow—check health, view demos and releases, add new demos—is covered. Missing update/delete operations, but this is intentionally delegated to the admin web interface, so no critical dead ends.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
A MCP server built for developers enabling Git based project management with project and personal…
Create, deploy, and operate MCP servers directly from your GitHub repositories.
An MCP server that let you interact with Cycloid.io Internal Development Portal and Platform
The official MCP Server for the Mux API
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA unified MCP server with composable tools for GitHub operations, file management, shell execution, kanban boards, Discord messaging, and package management. Features role-based security, HTTP/stdio transports, and a web-based development UI.
- FlicenseNot gradedqualityDmaintenanceStandalone MCP server for GitHub that enables repository management, branch operations, pull request handling, and commit retrieval via tools listed in the README.1
- FlicenseNot gradedqualityBmaintenanceA minimal MCP server for homelab environments, providing demo tools like ping and echo over Streamable HTTP for testing client-server integration.
- FlicenseNot gradedqualityCmaintenanceA minimal MCP server demo with tools for ping, addition, and fetching current UTC time.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/berbotu/berbotu-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server