Skip to main content
Glama

mcp-server

CI Go MCP License

A Model Context Protocol server that lets an AI coding agent find out whether anyone has shared a solution to a Coding Challenge, and in which language.

The protocol is implemented from the specification rather than through an SDK: JSON-RPC 2.0 over stdio, one compact message per line, in Go with no dependencies outside the standard library.

Built as a solution to Coding Challenge #104 — MCP Server for AI Agents. Its verdict on the official SDK is the interesting part:

$ node interop/client.mjs ./mcp-server
  PASS  initialize completed
  PASS  tools/list returned every tool
  PASS  the finder declares an output schema
  PASS  an unknown tool is an invalid-params error
  PASS  bad arguments are an invalid-params error
  PASS  a miss is not reported as an error
  ...
25 passed, 0 failed

Connecting an agent

{
  "mcpServers": {
    "coding-challenges": { "command": "mcp-server" }
  }
}

go install github.com/arclops/mcp-server@latest, then point the client at the binary with no arguments. Diagnostics go to stderr; stdout carries only protocol messages, because anything else on it corrupts the connection.

Related MCP server: acta-mcp

The tools

Tool

Arguments

Returns

hello

name

Hello, <name>. The connectivity check: it proves the handshake, the tool listing and a call all work before anything depends on the network

CodingChallengesSolutionFinder

challenge

Links to the pages listing shared solutions for the challenge that best matches the name

CodingChallengesFindSolution

challenge, language

The individual solutions for one challenge, filtered to one language

CodingChallengesListChallenges

Every challenge that has shared solutions, with links

Asked for solutions to wc written in Go, against the real repository:

Build your own wc Tool has 159 shared solution(s); 42 are written in Go.
https://github.com/CodingChallengesFYI/SharedSolutions/blob/main/Solutions/challenge-wc.md

1. wc-tool by andrenbrandao
   https://github.com/andrenbrandao/wc-tool
2. wc-go by praveshdev3
   https://github.com/praveshdev3/wc-go

Watching the protocol

mcp-server inspect performs the conversation the MCP Inspector performs — initialize, the initialized notification, tools/list and some tool calls — and prints the actual JSON-RPC in both directions:

$ mcp-server inspect
connection: stdio, one JSON-RPC message per line

--> {
  "id": 1,
  "jsonrpc": "2.0",
  "method": "initialize",
  "params": { "protocolVersion": "2025-11-25", "capabilities": {}, ... }
}
<-- {
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "protocolVersion": "2025-11-25",
    "capabilities": { "tools": {} },
    "serverInfo": { "name": "coding-challenges", ... },
    "instructions": "This server reads the Coding Challenges ..."
  }
}

-challenge NAME -language NAME adds the two lookups, so the whole thing can be demonstrated in one command:

$ mcp-server inspect -challenge bitcaskk
...
No challenge matching "bitcaskk" is listed in the shared solutions repository.

Closest titles:

- Build Your Own Bitcask

The protocol, by hand

Concern

What this server does

Transport

stdio, newline delimited JSON-RPC. A message must not contain an embedded newline, and a final message with no newline after it is still read

Revision

2025-11-25, with 2025-06-18 also spoken. Anything else is answered with 2025-11-25 and the client decides whether to continue

Lifecycle

initialize → result, then notifications/initialized. The client counts as initialized once it has been told how to talk to us, so a client that skips the notification still works

Capabilities

tools only. Nothing is claimed that is not implemented

Requests

ping, tools/list, tools/call

Notifications

Never answered, not even with an error: the client cannot correlate a reply with anything

Unknown method

-32601

Unparseable message

-32700 with a null id, and batched arrays are refused with -32600 rather than half-answered

Unknown tool, or arguments that do not match the tool's schema

-32602. The call was never valid, so it is not a result

A tool that fails while doing its job

A result with isError: true, because the model should read it and react rather than see a broken connection

A challenge that is not listed

Not an error either: an answer, with the closest titles to try

A panicking tool

Recovered, reported as a failed call, and the connection stays up

Message size

Capped, so a malformed stream cannot make the server allocate without bound

Every tool declares an outputSchema and returns matching structuredContent, alongside a text block written for a model to read. The tools are annotated readOnlyHint: true because none of them changes anything.

Design notes

  • The protocol is implemented, not imported. There is no Go SDK in the dependency list, so the transport framing, the lifecycle, the error codes and the negotiated revision are all visible in a few hundred lines of this repository rather than behind a library. The check that matters is not "does it compile against a library" but "does the official SDK accept what it says", which is what interop/ answers.

  • The instruction field is used for what it is for. Clients may put instructions into the model's context, so it explains how the three finder tools fit together instead of describing each one twice.

  • "Not found" is an answer, not an error. A model that mistypes a challenge name gets the closest titles and can retry in the same turn. Turning that into a failed call would make it give up or apologise.

  • The parsers are tolerant on purpose. The repository is written by hand by hundreds of contributors: rows omit the closing pipe, row numbers repeat, authors are plain text instead of links, TypeScript is spelled four ways and JavaScript appears as JacaScript. All of that is in the test fixtures, taken from the real files rather than invented.

  • Pages are cached for five minutes. A conversation with an agent asks the same question repeatedly; hammering GitHub for it would be rude and slow.

  • An empty table is not a missing table. A page whose table has no rows is a challenge nobody has solved; a page with no table at all means the format changed, and that is reported as an error.

  • Language names are folded: js, node, node.js and JacaScript all mean JavaScript, so a request for golang matches a row saying Go.

Testing

go test ./...            # 87 tests, 86-96% coverage per package
go test ./... -race
node interop/client.mjs ./mcp-server        # the official SDK, fixture data
node interop/client.mjs ./mcp-server --live # the official SDK, real GitHub
  • Protocol tests drive a server over pipes exactly as stdio does, and cover the handshake, version negotiation, the catalogue, every tool call, unknown methods, malformed JSON, batch arrays, blank lines, notifications that must not be answered, a panicking tool, and closing the input to shut down.

  • Parser tests run against the real repository files kept in testdata: a real README, a real solutions page with more than 150 rows, and a real one-row page. They assert the awkward rows specifically, because those are the ones that break.

  • Finder tests use an httptest server, so the suite is deterministic and offline. They cover caching and its expiry, connection failures, 404s, empty documents, a page with no table, and context cancellation.

  • Interoperability is checked against the official TypeScript SDK, which validates every reply against its own schemas. It runs in CI on every push.

  • The binary is tested as a binary: one test builds it, spawns it and drives it through real pipes, and another asserts that stdout carries nothing but protocol messages even with logging on.

Challenge steps

Step

Requirement

Where

1

A hello tool taking a string and returning Hello, <string>

internal/tools

2

Driven from the MCP Inspector

mcp-server inspect prints the same conversation

3

CodingChallengesSolutionFinder reading the shared solutions README

internal/challenges/parse.go, finder.go

4

Handle GitHub being unreachable, the format changing, and a challenge not being listed

finder.go errors, ParseSolutions, suggestions

5

Added to an AI coding agent

see the client configuration above

6

Solutions for a challenge in a particular language

CodingChallengesFindSolution

Going further

More tools

CodingChallengesListChallenges

Limitations

  • No commercial agent is installed in the development environment, so step 5 is covered by the configuration snippet and by driving the same stdio transport with the official SDK rather than by a screenshot from an editor.

  • Only the stdio transport is implemented. Streamable HTTP is a larger surface (sessions, resumability, authorization) and half of it would be worse than none.

  • No resources or prompts: the server declares only the tools capability.

  • The tool list is fixed for the lifetime of the process, so listChanged is false and no list-changed notification is ever sent.

License

MIT. See LICENSE.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables contributing, challenging, discovering, verifying, and querying contestable public records from AI coding tools via MCP.
    6
    49
    1
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables querying a personal GitHub repository of solved LeetCode problems via natural language, including topic-based search and live retrieval of solution code with difficulty and tags.
    1
    -