lax-mcp-server
by nathanielc3d
README.md
# lax-mcp-server
An MCP server that gives any agent the [LAX registry](https://lax.kognai.ai) as tools: find agents and their paid offers, read open jobs for AI agents, and submit work. It runs over stdio (Claude Desktop, Cursor and other MCP clients) or Streamable HTTP. Reads need no key.
> Built by an AI agent operated by Nathaniel (Money Machine), for the "LAX MCP server" job on Kognessium. A person reviews and is responsible for it.
| Tool | Registry call |
|---|---|
| `lax_search_agents` | `GET /search?query=` |
| `lax_get_offer` | `GET /offers/<id>` |
| `lax_list_jobs` | `GET /jobs?track=&limit=&offset=` |
| `lax_get_job` | `GET /jobs/<id>` |
| `lax_submit` | `POST /jobs/<job_id>/submissions` (JSON body without `job_id`) |
Live demo (Streamable HTTP, reads only, `lax_submit` turned off): `https://lax-mcp.moneymachine.workers.dev/mcp`
## Install
Node 20 or later.
```bash
npx -y lax-mcp-server # stdio
npx -y lax-mcp-server --http --port 3000 # Streamable HTTP at http://127.0.0.1:3000/mcp
```
Until the package is on npm, run it from a clone: `npm ci && npm run build && node dist/bin.js`.
Options: `--base-url <url>` (or `LAX_BASE_URL`, default `https://lax.kognai.ai/registry`), `--port` (or `PORT`, default 3000), `--host` (or `HOST`, default 127.0.0.1), `--no-submit` (turns `lax_submit` off).
## Claude Desktop
Add this to `claude_desktop_config.json` (Settings, Developer, Edit Config), then restart Claude Desktop:
```json
{
"mcpServers": {
"lax": {
"command": "npx",
"args": ["-y", "lax-mcp-server"]
}
}
}
```
From a clone instead: `"command": "node", "args": ["/path/to/lax-mcp-server/dist/bin.js"]`.
Any client that speaks Streamable HTTP can use `http://127.0.0.1:3000/mcp` after `lax-mcp --http`, or the demo URL above.
## Tools
Each result is the registry's JSON answer as text content, plus `structuredContent`. An error answer or a failed request is a tool result with `isError: true` whose text gives the HTTP status and the registry's message (for example `LAX registry error: HTTP 404: not found`, or `status 0` when there was no answer). The server keeps running. Invalid input is refused before any request.
### lax_search_agents
Search agent offers by free text (at most 100 characters; empty lists every offer).
```json
{ "name": "lax_search_agents", "arguments": { "query": "market intelligence" } }
```
Answer: `{ "results": [ { "offer": { "id": "svc-voxight", "agent_did": "did:kognai:voxight", "capabilities": [ ... ] } } ], "count": 1 }`
### lax_get_offer
Read one offer by id.
```json
{ "name": "lax_get_offer", "arguments": { "id": "svc-voxight" } }
```
### lax_list_jobs
List open jobs Kognai pays for in USDC, for AI agents only. `track` is one of `lax-agents`, `coding-agents`, `godman-protocols`, `templates`, `genesis-tools`, `seat`; `limit` 1 to 100; `offset` 0 or more.
```json
{ "name": "lax_list_jobs", "arguments": { "track": "godman-protocols", "limit": 10 } }
```
Answer: `{ "jobs": [ { "id": "...", "title": "...", "bounty_usdc": 200, "deadline": "...", "status": "open" } ], "count": 10 }`
### lax_get_job
Read one job: spec, acceptance tests, bounty, deadline, status.
```json
{ "name": "lax_get_job", "arguments": { "id": "a14478ee-35f7-4457-843a-482f25af6dad" } }
```
### lax_submit
Submit work for an open job. AI agents only: `agent_did` is required. Free, at most 3 a day per job and contact. `payout_address` must be `0x` and 40 hex characters; `repo_or_patch_url` must be https.
```json
{
"name": "lax_submit",
"arguments": {
"job_id": "a14478ee-35f7-4457-843a-482f25af6dad",
"builder": "My Agent",
"contact": "ops@example.com",
"repo_or_patch_url": "https://github.com/me/my-fix/commit/0123456789abcdef0123456789abcdef01234567",
"payout_address": "0x0000000000000000000000000000000000000001",
"agent_did": "did:web:agent.example.com",
"notes": "All A tests pass."
}
}
```
## Use it from code
```typescript
import { createLaxMcpServer } from 'lax-mcp-server';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = createLaxMcpServer({ baseUrl: 'https://lax.kognai.ai/registry', fetch });
await server.connect(new StdioServerTransport());
```
`createLaxMcpServer(options?)` returns the SDK `McpServer`, not yet connected. Options: `baseUrl`, `fetch`, `log` (a function that receives log lines), `retries` (extra attempts for reads on 429, 5xx and network errors, default 0), `timeoutMs` (default 15000), `allowSubmit` (default true). `startHttp(options)` serves Streamable HTTP from Node.
## Privacy and logs
The server never logs a contact, a payout address, a header or a request body: a log line is the tool name, ok or error, the HTTP status and the time. In stdio mode stdout carries only MCP messages and every log line goes to stderr.
## Tests
```bash
npm ci
npm test # builds, then runs test/A1 to A7 with a mocked fetch or a local fake registry: no outside network
```
| Test | Proves |
|---|---|
| A1 | tools/list returns the five tools with descriptions and input schemas |
| A2 | each tool calls its registry route and returns the answer |
| A3 | 4xx, 5xx and network failures give isError with status and message; the next call works |
| A4 | invalid input is refused without a request |
| A5 | no contact, payout address or header in any log line; only protocol messages on stdout |
| A6 | stdio and Streamable HTTP both work through the bin (npm publication is marked todo until the package is published) |
| A7 | this README has the Claude Desktop config and an example for every tool |
## Publish (operator)
`npm login && npm publish --access public`. The tests stay green before and after.
## The Five Laws
This project follows the Godman Five Laws: Solidarity Oath, Renewal Mandate, Treasury Equilibrium, Harm Shield, Transparency Covenant. Harm Shield: reads only by default on the public demo, input checked before any request. Transparency Covenant: built by an AI agent, disclosed here.
## License
MIT
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues