Skip to main content
Glama
devnull-mcp

devnull-mcp

by sfolador

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

devnull_commit

Publish a commit (up to 4000 characters), optionally as a reply (reply_to takes a short hash, UUID or link).

devnull_whoami

Shows which local SSH key /dev/null recognizes as yours. Posts nothing.

devnull_get_user

Public profile of a user by GitHub username.

devnull_list_commits

A user's latest commits (or replies), 20 per page with a cursor.

devnull_get_commit

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>.pub next 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 build

Register 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.js

Or add it to any MCP client configuration:

{
  "mcpServers": {
    "devnull": {
      "command": "node",
      "args": ["/absolute/path/to/devnull-mcp/dist/index.js"]
    }
  }
}

Environment variables

Variable

Purpose

DEVNULL_SSH_KEY

Path to the private key to sign with, when auto-discovery picks the wrong one. Its public key is derived with ssh-keygen -y.

DEVNULL_URL

Another instance, for development. Must be https://, or http://localhost.

How a commit works

  1. The public keys from ssh-add -L and ~/.ssh/*.pub are sent to POST /api/cli/key-lookups, which answers with the one that belongs to a /dev/null user. Public keys are public: GitHub publishes them at https://github.com/<you>.keys.

  2. The payload timestamp\nnonce\nreply_to\nmessage is signed with that key in the devnull-commit namespace. The signature is only valid for /dev/null commits.

  3. 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 stdio

Available Tools

5 tools
devnull_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.

NameRequiredDescriptionDefault
messageYesThe commit message to publish, plain text.
reply_toNoOptional: the short hash (as shown on /dev/null), UUID or link of the commit to reply to.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 commitB
Read-only

One public /dev/null commit by UUID or link.

NameRequiredDescriptionDefault
commitYesThe commit UUID or its /dev/null link.

TDQS

B3.2/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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 userB
Read-only

Public profile of a /dev/null user by GitHub username: bio, links, commit, follower and following counts.

NameRequiredDescriptionDefault
usernameYesGitHub username, with or without a leading @.

TDQS

B3.4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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 commitsA
Read-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.

NameRequiredDescriptionDefault
cursorNonext_cursor from a previous page.
repliesNotrue to list replies instead of top-level commits.
usernameYesGitHub username, with or without a leading @.

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 signsA
Read-only

Shows which local SSH key /dev/null recognizes as yours, without posting anything.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

  1. 5 tool updatesv0.1.0
    • First observeddevnull_commit
    • First observeddevnull_get_commit
    • First observeddevnull_get_user
    • First observeddevnull_list_commits
    • First observeddevnull_whoami

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables 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.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Remote 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
  • F
    license
    Not graded
    quality
    D
    maintenance
    A 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.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables 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 npm
    MIT