about-utkarsh-mcp
Click on "Install 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., "@about-utkarsh-mcptell me about Utkarsh's background and skills"
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.
about-utkarsh-mcp
An MCP (Model Context Protocol) server that exposes information about Utkarsh — bio, skills, work experience, and portfolio projects — to any MCP-compatible client (Claude, Claude Code, ChatGPT, Codex, etc.).
It ships two transports from one shared server implementation:
Transport | File | Used by |
stdio |
| Local clients that launch the server as a subprocess: Claude Desktop, Claude Code, Codex CLI |
Streamable HTTP (remote) |
| Remote clients that connect over a URL: ChatGPT connectors, remote Claude/Claude Code, any HTTP-based MCP client |
The remote HTTP transport is protected with OAuth 2.0, including Dynamic Client Registration (DCR, RFC 7591) — so a new MCP client can self-register and connect without any manual "create an API key" step, exactly as the MCP Authorization spec expects for remote servers.
Live deployment: https://about-utkarsh-mcp.onrender.com/mcp
Repo: https://github.com/utkarsh21123/about-utkarsh-mcp
Architecture
src/
data/profile.ts # Single source of truth: bio, skills, experience, projects
mcpServer.ts # Shared MCP server: tools + one resource, used by both transports
transports/
stdio.ts # Local subprocess transport
http.ts # Remote Streamable HTTP transport (OAuth-protected)
oauth/
store.ts # In-memory client/auth-code store
router.ts # DCR, authorize (PKCE), token, discovery metadata endpointsMCP tools exposed
get_bio— name, title, location, experience summary, linksget_skills— skills by category (languages/frontend/backend/databases/infra/spoken)get_experience— work historylist_projects— all portfolio projects (summary)get_project_details— full detail for one named projectget_contact— how to reach out
Plus one resource: profile://utkarsh/full (the whole profile as JSON).
OAuth / DCR flow (remote HTTP transport)
Client discovers the server via
GET /.well-known/oauth-protected-resource(RFC 9728) andGET /.well-known/oauth-authorization-server(RFC 8414).Client dynamically registers itself:
POST /register(RFC 7591) — no pre-shared client id/secret needed.Client runs the standard Authorization Code + PKCE flow:
GET /authorize(a one-click "Approve" page — there's no personal login here, just consent to read a public profile) →POST /token.Client calls
POST/GET/DELETE /mcpwithAuthorization: Bearer <token>.
This was verified end-to-end (registration → authorize → token exchange →
authenticated initialize and tools/call) both locally and against the live
Render deployment.
Related MCP server: resume-mcp
Running it locally — full step by step
Prerequisites
Node.js 18+ (tested on Node 22) and npm
gitcurl(for manual testing) — optional but recommended
1. Clone and install
git clone https://github.com/utkarsh21123/about-utkarsh-mcp.git
cd about-utkarsh-mcp
npm install2. Build
npm run buildThis compiles src/ (TypeScript) to dist/ (JavaScript) via tsc. Re-run this
any time you edit a .ts file — the running server uses the compiled dist/ output.
3a. Run the stdio server (local client mode)
npm run start:stdioYou should see, on stderr (not stdout — stdout is reserved for the MCP JSON-RPC protocol):
about-utkarsh-mcp: stdio server readyIt's now waiting for a client to talk to it over stdin/stdout. Two ways to test:
Option A — connect a real client. Add this to Claude Desktop's
claude_desktop_config.json or Claude Code's .mcp.json:
{
"mcpServers": {
"about-utkarsh": {
"command": "node",
"args": ["/absolute/path/to/about-utkarsh-mcp/dist/transports/stdio.js"]
}
}
}Or with the Claude Code CLI:
claude mcp add about-utkarsh -- node /absolute/path/to/about-utkarsh-mcp/dist/transports/stdio.jsRestart the client, then ask it something like "What are Utkarsh's skills?" and confirm it invokes a tool (not just answers from general knowledge).
Option B — manual JSON-RPC test, no client needed:
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}\n{"jsonrpc":"2.0","method":"notifications/initialized"}\n{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_bio","arguments":{}}}\n' | node dist/transports/stdio.jsYou should get back an initialize response followed by a tools/call result
containing your bio as JSON.
3b. Run the HTTP server (remote client mode)
npm run start:httpDefaults to port 3000. You'll see:
about-utkarsh-mcp: HTTP server listening on port 3000
MCP endpoint: http://localhost:3000/mcp
OAuth discovery: http://localhost:3000/.well-known/oauth-authorization-server
Auth required: trueTo test without dealing with OAuth first (useful while developing):
REQUIRE_AUTH=false npm run start:http
curl -s -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'4. Full local test of the OAuth/DCR flow
With the server running (REQUIRE_AUTH=true, the default), in a second terminal:
URL=http://localhost:3000
# 1. Health check
curl -s $URL/health
# 2. Discovery metadata
curl -s $URL/.well-known/oauth-authorization-server
curl -s $URL/.well-known/oauth-protected-resource
# 3. Confirm auth is enforced (expect 401)
curl -s -i -X POST $URL/mcp -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | head -6
# 4. Dynamic Client Registration
REG=$(curl -s -X POST $URL/register -H "Content-Type: application/json" -d '{
"client_name": "Test Client",
"redirect_uris": ["https://client.example.com/callback"],
"token_endpoint_auth_method": "none"
}')
echo "$REG"
CLIENT_ID=$(echo "$REG" | node -e "process.stdin.on('data',d=>console.log(JSON.parse(d).client_id))")
# 5. PKCE challenge/verifier
VERIFIER=$(node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))")
CHALLENGE=$(node -e "console.log(require('crypto').createHash('sha256').update('$VERIFIER').digest('base64url'))")
# 6. Authorize + approve (simulates clicking "Approve" in the browser)
LOC=$(curl -s -o /dev/null -w '%{redirect_url}' "$URL/authorize/approve?client_id=$CLIENT_ID&redirect_uri=https://client.example.com/callback&state=xyz&code_challenge=$CHALLENGE&code_challenge_method=S256")
CODE=$(node -e "console.log(new URL('$LOC').searchParams.get('code'))")
# 7. Exchange code for token
TOKEN_RESP=$(curl -s -X POST $URL/token -H "Content-Type: application/json" \
-d "{\"grant_type\":\"authorization_code\",\"code\":\"$CODE\",\"redirect_uri\":\"https://client.example.com/callback\",\"client_id\":\"$CLIENT_ID\",\"code_verifier\":\"$VERIFIER\"}")
echo "$TOKEN_RESP"
ACCESS_TOKEN=$(echo "$TOKEN_RESP" | node -e "process.stdin.on('data',d=>console.log(JSON.parse(d).access_token))")
# 8. Authenticated MCP call
curl -s -i -X POST $URL/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'Expect a 200 OK on the last call with an mcp-session-id header and the
server's initialize payload in the body.
5. (Optional) Develop without rebuilding each time
npm run dev:stdio # tsx, runs src/transports/stdio.ts directly
npm run dev:http # tsx, runs src/transports/http.ts directlyThese use tsx to run the TypeScript source directly — no npm run build step
needed between edits.
Deployment (remote HTTP server)
The included Dockerfile builds a production image; render.yaml is a one-click
blueprint for Render, but this deploys the same way on
Railway, Fly.io, or any container host.
Render (recommended, free tier available)
Push this repo to GitHub.
On Render: New → Blueprint, point it at the repo —
render.yamlconfigures everything (including generating a randomJWT_SECRET).Once deployed, set
PUBLIC_BASE_URLto the assignedhttps://<app>.onrender.comURL in the service's environment settings and it'll redeploy automatically, so OAuth metadata advertises the correct absolute URLs.Your MCP endpoint is
https://<app>.onrender.com/mcp.
Note on the free tier: Render's free instances spin down after a period of inactivity and take up to ~50 seconds to spin back up on the next request. If you need consistently fast/always-on responses, upgrade the Render service to a paid instance type.
Any other Docker host (Railway, Fly.io, a VPS, etc.)
docker build -t about-utkarsh-mcp .
docker run -p 3000:3000 \
-e JWT_SECRET=$(node -e "console.log(require('crypto').randomBytes(48).toString('hex'))") \
-e PUBLIC_BASE_URL=https://your-deployed-domain.example.com \
about-utkarsh-mcpConnecting clients
Claude Desktop / Claude Code (local, stdio)
See step 3a above.
Claude (remote, HTTP + OAuth)
In Claude's connector settings, add a custom connector pointing at:
https://about-utkarsh-mcp.onrender.com/mcpClaude auto-discovers the OAuth metadata, registers itself via DCR, and walks you through the one-click approval — no manual credentials required.
ChatGPT (connectors / remote MCP)
Same idea: add a custom connector pointing at the same /mcp URL. ChatGPT
performs the same discovery → DCR → OAuth flow.
Codex
Codex CLI (local): same config as Claude Code, pointing at
node dist/transports/stdio.js.Codex web/cloud (remote): use the deployed
/mcpURL as above.
Notes on the OAuth implementation
Storage for registered clients/auth codes is in-memory (
src/oauth/store.ts) — fine for an assessment/demo; swap in a real database for production so registrations survive restarts and multiple instances.Access tokens are short-lived HS256 JWTs (1 hour). There's no user login screen because the "resource" being protected is a public profile with no per-user data — the approval screen exists to satisfy the OAuth consent step the MCP spec expects, not to gate a private account.
PKCE (RFC 7636) is enforced for public clients (
token_endpoint_auth_method: none), which is what DCR-registered MCP clients typically use.
Keeping the data current
Everything the tools return lives in src/data/profile.ts. Update that file,
npm run build, and redeploy to change what the server tells clients about Utkarsh.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/utkarsh21123/about-utkarsh-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server