devnull-mcp
Click on "Deploy 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., "@devnull-mcppost a commit saying I finally fixed the race condition"
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.
devnull-mcp
An MCP server for /dev/null, the plain-text social network for developers. It lets Claude (or any MCP client) commit to /dev/null as you, and read public profiles and commits.
There is no login. A commit is signed locally with ssh-keygen -Y sign, using an SSH key that is on
your GitHub account, and /dev/null checks the signature against the keys GitHub publishes for you,
exactly like the official curl -fsSL https://dev-null.sh/commit | bash script does.
Tools
Tool | What it does |
| Publish a commit (up to 4000 characters), optionally as a reply ( |
| Shows which local SSH key /dev/null recognizes as yours. Posts nothing. |
| Public profile of a user by GitHub username. |
| A user's latest commits (or replies), 20 per page with a cursor. |
| One commit by UUID or link. |
Related MCP server: notes-mcp
Requirements
Node.js 20 or newer,
ssh-keygen(OpenSSH 8.0+).An Ed25519 or RSA key that is on your GitHub account, either loaded in your SSH agent or as
~/.ssh/<name>with~/.ssh/<name>.pubnext to it. Passphrase-protected keys must be in the agent (ssh-add ~/.ssh/<name>), because the server has no terminal to ask for the passphrase.Having signed in once on https://dev-null.sh with GitHub.
Install
npm install
npm run buildRegister it with Claude Code (user scope, so it is available in every project):
claude mcp add --scope user devnull -- node /absolute/path/to/devnull-mcp/dist/index.jsOr add it to any MCP client configuration:
{
"mcpServers": {
"devnull": {
"command": "node",
"args": ["/absolute/path/to/devnull-mcp/dist/index.js"]
}
}
}Environment variables
Variable | Purpose |
| Path to the private key to sign with, when auto-discovery picks the wrong one. Its public key is derived with |
| Another instance, for development. Must be |
How a commit works
The public keys from
ssh-add -Land~/.ssh/*.pubare sent toPOST /api/cli/key-lookups, which answers with the one that belongs to a /dev/null user. Public keys are public: GitHub publishes them athttps://github.com/<you>.keys.The payload
timestamp\nnonce\nreply_to\nmessageis signed with that key in thedevnull-commitnamespace. The signature is only valid for /dev/null commits.The payload and signature go to
POST /api/cli/commits, which answers with the commit link.
Private keys are never read by this code: ssh-keygen or the agent uses them. Temporary files are
written to a fresh private directory that is deleted afterwards.
Development
npm test # node:test suite, includes a real ssh-keygen sign/verify round trip
npm run typecheck
npm run dev # run from sources over stdioAvailable Tools
5 toolsdevnull_commitCommit to /dev/nullA
Publish a plain-text post ("commit") on /dev/null (dev-null.sh) as the user, or reply to an existing commit. The message is signed locally with the SSH key that is on the user's GitHub account. Max 4000 characters. Commits are public and the user is rate limited to 10 a minute, so only call this when the user asked to post.
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | The commit message to publish, plain text. | |
| reply_to | No | Optional: the short hash (as shown on /dev/null), UUID or link of the commit to reply to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing the signing mechanism (local SSH key tied to the user's GitHub account), the 4000-character cap, that posts are public, and a concrete rate limit of 10 per minute. These are exactly the operational constraints an agent needs before mutating state.
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?
Three sentences, front-loaded with the core action, then the security/size facts, then the call condition. Nothing is repeated and every sentence carries load-bearing information.
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 two-parameter mutation tool with no output schema, the description covers purpose, auth, size limits, visibility, rate limits, and a usage guard. An agent has everything needed to decide whether to call and to call it correctly.
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 coverage is 100%, so both parameters are already documented, including the accepted identifier forms for reply_to (short hash, UUID, or link). The description reinforces the reply concept and the length limit but adds no syntax or format detail the schema lacks, so the baseline 3 applies.
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?
States a specific verb (publish) and resource (a plain-text 'commit' on /dev/null) plus a secondary mode (reply to an existing commit). The write orientation makes it unambiguously distinct from the read-only siblings devnull_get_commit, devnull_list_commits, devnull_get_user and devnull_whoami.
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?
Explicitly gates invocation with 'only call this when the user asked to post', which is a clear when-not condition, and the reply mode is spelled out. It doesn't name a sibling alternative by name, but no sibling competes for this function, so the routing risk is low.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
devnull_get_commitGet a commitBRead-only
One public /dev/null commit by UUID or link.
| Name | Required | Description | Default |
|---|---|---|---|
| commit | Yes | The commit UUID or its /dev/null link. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only and open-world behavior, so the safety profile is covered. The description adds useful scope by saying the commit must be "public" and can be referenced by UUID or link, though it does not describe error behavior or what the returned commit contains.
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 definition is a single short sentence with no wasted text and the resource scope is front-loaded. It is slightly telegraphic, but it remains readable and efficient.
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 simple one-parameter lookup with full schema coverage and annotations covering safety/open-world behavior, the description is largely complete. The main omission is that it does not clarify the shape of the returned commit, though no output schema exists to compensate.
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 has 100% description coverage and already documents the single `commit` parameter as a UUID or `/dev/null` link. The description reinforces those accepted identifier forms but adds no syntax or format details beyond the schema, so baseline 3 is appropriate.
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 states a specific retrieval action for a single `/dev/null` commit and identifies accepted lookup forms (UUID or link). It is clear enough to distinguish this from a list operation, but it does not explicitly differentiate itself from sibling tools such as `devnull_list_commits`.
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 implies use for a single commit via the word "One," but gives no explicit when-to-use guidance, prerequisites, or conditions for choosing this over `devnull_list_commits` or other commit-related siblings. The agent must infer the selection rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
devnull_get_userGet a /dev/null userBRead-only
Public profile of a /dev/null user by GitHub username: bio, links, commit, follower and following counts.
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes | GitHub username, with or without a leading @. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds that the data is the public profile and lists which counters come back, which is useful context beyond annotations. It says nothing about missing/unknown usernames or rate limiting on the external source.
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?
A single front-loaded sentence with the resource first and the returned fields after the colon; no filler or redundancy.
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 one-parameter read tool with no output schema, the description conveys the subject and the returned field set, which is enough to call it correctly. The one real gap is the missing contrast with devnull_whoami, which shares the same conceptual space.
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 coverage is 100% and the schema already describes the username and the optional leading '@'. The description only restates 'by GitHub username', adding no new format or edge-case detail, so the baseline 3 applies.
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?
States a specific verb+resource: fetches a public user profile by GitHub username, and enumerates the fields returned (bio, links, commit/follower/following counts). It never distinguishes itself from the sibling devnull_whoami, which an agent could plausibly confuse with 'my own profile'.
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?
No statement of when to use this versus devnull_whoami or the commit-related siblings, and no prerequisites or error conditions (e.g. unknown username). Usage must be inferred from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
devnull_list_commitsList a user’s commitsARead-only
The latest approved commits of a /dev/null user (20 per page). Set replies=true for their replies instead of top-level commits; pass next_cursor to page.
| Name | Required | Description | Default |
|---|---|---|---|
| cursor | No | next_cursor from a previous page. | |
| replies | No | true to list replies instead of top-level commits. | |
| username | Yes | GitHub username, with or without a leading @. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint and openWorldHint already declared, the description usefully adds the page size (20) and the 'approved' filtering rule, which the annotations cannot convey. It says nothing about behavior for unknown users, whether more pages exist, or ordering beyond 'latest', leaving real gaps for a paged 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?
Two short sentences, no filler, and the core resource plus page size is front-loaded before the mode/paging notes. Every clause carries distinct information.
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 three-parameter, read-only list tool with full schema coverage, the description covers the essentials and adds page size and the approved filter. The only remaining gap is return shape, but with no output schema and a conventional list response that is a minor omission.
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 coverage is 100%, so all three parameters are already documented, and the description's use of replies and next_cursor is consistent with the schema's replies and cursor fields. It adds no syntax or format detail beyond the schema, so the baseline 3 applies.
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?
It states a specific resource and scope: the latest *approved* commits for a given /dev/null user, paginated at 20 per page. That is far more precise than the title alone and implicitly separates it from devnull_get_commit (single commit) and devnull_commit (write), though it never names those siblings explicitly.
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 explains how to switch modes (replies=true) and how to page (next_cursor), which is usage-adjacent guidance. It never says when to reach for this tool instead of devnull_get_commit or devnull_whoami, so selection guidance remains implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
devnull_whoamiWhich key signsARead-only
Shows which local SSH key /dev/null recognizes as yours, without posting anything.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is largely covered. The description adds a useful distinction the annotations do not: it inspects a *local* key and posts nothing, clarifying the write posture. It still says nothing about what comes back (fingerprint? key path? user identity?).
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?
A single front-loaded sentence with no filler; every clause ('local', 'without posting anything') carries meaning.
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 zero-param read-only identity check with annotations and no output schema, the description is nearly sufficient; only the shape of the returned identification (key fingerprint, user name) is left unstated.
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?
Zero parameters, so the baseline is 4; the schema confirms an empty object and there is nothing for the description to clarify.
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?
States a specific verb ('shows which') and a specific resource ('local SSH key ... recognizes as yours'), which is clearly an identity/key lookup distinct from the commit- and user-oriented siblings. The '/dev/null' framing is a bit cute, but the operation is identifiable.
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?
No guidance on when to call this versus devnull_get_user, nor any preconditions (e.g., whether an SSH key must be configured). The usage is only inferable from the description of what it does.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
devnull_commit - First observed
devnull_get_commit - First observed
devnull_get_user - First observed
devnull_list_commits - First observed
devnull_whoami
TDQS
Scored across 5 tools
Each tool targets a distinct operation and resource: posting (devnull_commit), reading a single commit, listing commits, fetching a user profile, and checking identity (whoami). The write tool versus read tools boundary is clear, and get_commit vs list_commits is unambiguous.
All tools share the devnull_ prefix, which is consistent. The get_/list_ verb_noun pattern is used for three tools, but devnull_commit and devnull_whoami deviate slightly, making it mostly consistent with minor exceptions.
Five tools are well-scoped for a simple social posting service, covering posting, reading, listing, profile, and identity without excess. Each tool earns its place.
The core lifecycle is covered: post, read a commit, list commits, view user profiles, and verify identity. Minor gaps like editing/deleting a commit or browsing followers/following exist, but agents can work around them for the stated purpose.
Maintenance
Related MCP Connectors
Your Gmail, Calendar, Drive, GitHub, Oura, wallet and confirmed profile facts in any MCP client.
Hosted X (Twitter) MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Remote streamable-HTTP MCP server running on a single Cloudflare Worker. Your assistant gets live Airbnb, Amazon, Booking.com, Google Flights, Maps and Reddit data, social search on X, Instagram and TikTok, the Meta Ad Library, and image/video generation without any keys. Connect your own accounts to let it send WhatsApp or Telegram messages, work an IMAP inbox, manage Meta Ads campaigns and publish to X and LinkedIn. OAuth 2.1 with PKCE; stored credentials are AES-256-GCM encrypted.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables GitHub repository operations (list/read files, create branches, commit files, open/list PRs) via an authless remote MCP server that keeps your GitHub token encrypted on Cloudflare, with access limited to allowed repositories.-
- AlicenseNot gradedqualityCmaintenanceRemote MCP server that exposes a personal git repository of markdown notes to Claude, enabling reading, writing, searching, and running scripts with automatic git commits and GitHub OAuth authentication.MIT
- FlicenseNot gradedqualityDmaintenanceA single-user MCP server that exposes your GitHub activity to Claude via three read-only tools: recent commits, open pull requests, and repository summaries. Deployed as a Vercel function using Streamable HTTP.-
- AlicenseNot gradedqualityCmaintenanceEnables Claude and other MCP clients to read and write GitHub repositories, pull requests, issues, files, branches, commits, releases, and more using a personal access token without OAuth.281 npmMIT