My portfolio is an MCP server: connect your agent
My portfolio is also a Model Context Protocol server. Point Claude Code or any MCP client at it and ask whether I fit your role: it's read-only, open to any client, and speaks the stateless 2026-07-28 revision as well as the older handshake.
Connect Claude Code
claude mcp add --transport http rishabh https://rishabhsingh.ca/api/mcp
Then ask, for example, "Use rishabh's match_job tool on this posting" and paste a job description or link.
Connect another client
Any client that supports remote MCP servers over Streamable HTTP needs only the URL. In a JSON config such as Cursor's mcp.json:
{ "mcpServers": { "rishabh": { "url": "https://rishabhsingh.ca/api/mcp" } } }
Call it with curl
Under the 2026-07-28 revision there's no handshake: every request carries its protocol version and client details in _meta, and the method and tool name travel in headers too, so a gateway can route without reading the body. Ask what the server offers:
curl -s https://rishabhsingh.ca/api/mcp \
-H 'content-type: application/json' -H 'accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2026-07-28' -H 'Mcp-Method: server/discover' \
-d '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{},"io.modelcontextprotocol/clientInfo":{"name":"curl","version":"1"}}}}'
Call a tool:
curl -s https://rishabhsingh.ca/api/mcp \
-H 'content-type: application/json' -H 'accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2026-07-28' -H 'Mcp-Method: tools/call' -H 'Mcp-Name: search_resume' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_resume","arguments":{"query":"ship LLM features to production","limit":1},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{},"io.modelcontextprotocol/clientInfo":{"name":"curl","version":"1"}}}}'
Tools, resources and prompts
- Tools, all read-only: get_profile, list_roles, get_role, search_resume (BM25 over the résumé), get_resume, match_job (the calibrated fit verdict for a posting's text or link) and tailor_resume (the résumé tailored to a posting, as JSON Resume).
- Resources: rishabh://resume.json, rishabh://model-card.md, rishabh://now and rishabh://experience/{id}, one per role and also a resource template.
- Prompts: tailor_resume and interview_brief.
Each past role is also its own server, with one tool per piece of work that returns the evidence: /api/mcp/nesteazy, /api/mcp/the-cabin-depot, /api/mcp/plato, /api/mcp/ibm-qradar-cloud, /api/mcp/geoffrey-stephens, /api/mcp/ibm-security. Chapter 2 of the portfolio connects to them live.
Agent2Agent (A2A)
The A2A agent card describes the same record for A2A 1.0 clients, with JSON-RPC at /api/a2a (send the header A2A-Version: 1.0). Its skills are ask_about_rishabh, match_job and get_resume, answered from the record with no model in the loop.
Why it's built this way
- The tool description is the prompt that picks the tool
- MCP dropped its handshake
- readOnlyHint is a hint, and a server can lie
The whole record is also plain text at llms.txt and llms-full.txt, and as an installable Agent Skill.