Skip to content

Instantly share code, notes, and snippets.

@ArjitJ
Created June 16, 2025 05:41
Show Gist options
  • Select an option

  • Save ArjitJ/cc7356bff1f782c03bf59a4f65a9d2d6 to your computer and use it in GitHub Desktop.

Select an option

Save ArjitJ/cc7356bff1f782c03bf59a4f65a9d2d6 to your computer and use it in GitHub Desktop.

🚀 MCP Server Setup Instructions

Follow the instructions below to set up your MCP server and complete the application process.


✅ Next Steps

Use the provided starter code to spin up a local MCP server.

  1. After running /apply <TWITTER/LINKEDIN REPLY URL> you will get a application key.

  2. Now you need to create an mcp server using the starter code given in this gist to submit your resume.

Use this command to connect Puch with your mcp server /mcp connect <SERVER URL (should be publicly accesible)>/mcp <AUTH TOKEN>

🔑 Important: Replace the placeholder token in the code with your actual application key.

  1. Puch will run a validation check against your Auth token (application key) and phone number

📞 Validation requires both the key and your phone number, formatted as {country_code}{number}without the + symbol.
Example: 919876543210 for an Indian number.

  1. Feed your resume to Puch: Create a tool that sends your resume in a format fit for an LLM

📎 Resume Tool Requirement:
Your server must include a resume tool that:

  • Accepts a local file (your resume).
  • Converts it to markdown text
  • Submits the data to the Puch AI MCP endpoint as a string.

Starter code

from typing import Annotated
from fastmcp import FastMCP
from fastmcp.server.auth.providers.bearer import BearerAuthProvider, RSAKeyPair
import markdownify
from mcp import ErrorData, McpError
from mcp.server.auth.provider import AccessToken
from mcp.types import INTERNAL_ERROR, INVALID_PARAMS, TextContent
from openai import BaseModel
from pydantic import AnyUrl, Field
import readabilipy
from pathlib import Path

TOKEN = "<generated_token>"
MY_NUMBER = "9189XXXXXXXX"  # Insert your number {91}{Your number}


class RichToolDescription(BaseModel):
    description: str
    use_when: str
    side_effects: str | None


class SimpleBearerAuthProvider(BearerAuthProvider):
    """
    A simple BearerAuthProvider that does not require any specific configuration.
    It allows any valid bearer token to access the MCP server.
    For a more complete implementation that can authenticate dynamically generated tokens,
    please use `BearerAuthProvider` with your public key or JWKS URI.
    """

    def __init__(self, token: str):
        k = RSAKeyPair.generate()
        super().__init__(
            public_key=k.public_key, jwks_uri=None, issuer=None, audience=None
        )
        self.token = token

    async def load_access_token(self, token: str) -> AccessToken | None:
        if token == self.token:
            return AccessToken(
                token=token,
                client_id="unknown",
                scopes=[],
                expires_at=None,  # No expiration for simplicity
            )
        return None


class Fetch:
    IGNORE_ROBOTS_TXT = True
    USER_AGENT = "Puch/1.0 (Autonomous)"

    @classmethod
    async def fetch_url(
        cls,
        url: str,
        user_agent: str,
        force_raw: bool = False,
    ) -> tuple[str, str]:
        """
        Fetch the URL and return the content in a form ready for the LLM, as well as a prefix string with status information.
        """
        from httpx import AsyncClient, HTTPError

        async with AsyncClient() as client:
            try:
                response = await client.get(
                    url,
                    follow_redirects=True,
                    headers={"User-Agent": user_agent},
                    timeout=30,
                )
            except HTTPError as e:
                raise McpError(
                    ErrorData(
                        code=INTERNAL_ERROR, message=f"Failed to fetch {url}: {e!r}"
                    )
                )
            if response.status_code >= 400:
                raise McpError(
                    ErrorData(
                        code=INTERNAL_ERROR,
                        message=f"Failed to fetch {url} - status code {response.status_code}",
                    )
                )

            page_raw = response.text

        content_type = response.headers.get("content-type", "")
        is_page_html = (
            "<html" in page_raw[:100] or "text/html" in content_type or not content_type
        )

        if is_page_html and not force_raw:
            return cls.extract_content_from_html(page_raw), ""

        return (
            page_raw,
            f"Content type {content_type} cannot be simplified to markdown, but here is the raw content:\n",
        )

    @staticmethod
    def extract_content_from_html(html: str) -> str:
        """Extract and convert HTML content to Markdown format.

        Args:
            html: Raw HTML content to process

        Returns:
            Simplified markdown version of the content
        """
        ret = readabilipy.simple_json.simple_json_from_html_string(
            html, use_readability=True
        )
        if not ret["content"]:
            return "<error>Page failed to be simplified from HTML</error>"
        content = markdownify.markdownify(
            ret["content"],
            heading_style=markdownify.ATX,
        )
        return content




mcp = FastMCP(
    "My MCP Server",
    auth=SimpleBearerAuthProvider(TOKEN),
)

ResumeToolDescription = RichToolDescription(
    description="Serve your resume in plain markdown.",
    use_when="Puch (or anyone) asks for your resume; this must return raw markdown, \
no extra formatting.",
    side_effects=None,
)

@mcp.tool(description=ResumeToolDescription.model_dump_json())
async def resume() -> str:
    """
    Return your resume exactly as markdown text.
    
    TODO: Implement this function to:
    1. Find and read your resume.
    2. Convert the resume to markdown format.
    3. Handle any errors gracefully.
    4. Return the resume as markdown text.
    """
    # TODO: Implement resume fetching logic
    raise NotImplementedError("Resume tool not implemented")


@mcp.tool
async def validate() -> str:
    """
    NOTE: This tool must be present in an MCP server used by puch.
    """
    return MY_NUMBER


FetchToolDescription = RichToolDescription(
    description="Fetch a URL and return its content.",
    use_when="Use this tool when the user provides a URL and asks for its content, or when the user wants to fetch a webpage.",
    side_effects="The user will receive the content of the requested URL in a simplified format, or raw HTML if requested.",
)


@mcp.tool(description=FetchToolDescription.model_dump_json())
async def fetch(
    url: Annotated[AnyUrl, Field(description="URL to fetch")],
    max_length: Annotated[
        int,
        Field(
            default=5000,
            description="Maximum number of characters to return.",
            gt=0,
            lt=1000000,
        ),
    ] = 5000,
    start_index: Annotated[
        int,
        Field(
            default=0,
            description="On return output starting at this character index, useful if a previous fetch was truncated and more context is required.",
            ge=0,
        ),
    ] = 0,
    raw: Annotated[
        bool,
        Field(
            default=False,
            description="Get the actual HTML content if the requested page, without simplification.",
        ),
    ] = False,
) -> list[TextContent]:
    """Fetch a URL and return its content."""
    url_str = str(url).strip()
    if not url:
        raise McpError(ErrorData(code=INVALID_PARAMS, message="URL is required"))

    content, prefix = await Fetch.fetch_url(url_str, Fetch.USER_AGENT, force_raw=raw)
    original_length = len(content)
    if start_index >= original_length:
        content = "<error>No more content available.</error>"
    else:
        truncated_content = content[start_index : start_index + max_length]
        if not truncated_content:
            content = "<error>No more content available.</error>"
        else:
            content = truncated_content
            actual_content_length = len(truncated_content)
            remaining_content = original_length - (start_index + actual_content_length)
            # Only add the prompt to continue fetching if there is still remaining content
            if actual_content_length == max_length and remaining_content > 0:
                next_start = start_index + actual_content_length
                content += f"\n\n<error>Content truncated. Call the fetch tool with a start_index of {next_start} to get more content.</error>"
    return [TextContent(type="text", text=f"{prefix}Contents of {url}:\n{content}")]


async def main():
    await mcp.run_async(
        "streamable-http",
        host="0.0.0.0",
        port=8085,
    )


if __name__ == "__main__":
    import asyncio

    asyncio.run(main())
@maroofgadiwale
Copy link
Copy Markdown

Can anyone please provide me the code ? I don't know why mcp is refusing to connect

@Akashgite1
Copy link
Copy Markdown

Akashgite1 commented Aug 17, 2025

Screenshot 2025-08-17 165433

i am done i guess right .........?

@maroofgadiwale
Copy link
Copy Markdown

Screenshot 2025-08-17 165433 i am done i guess right .........?

Can you share your mcp code and even tell me like what do using ngrok local server?

@maroofgadiwale
Copy link
Copy Markdown


connect

This is the issue I am encountering

@Aditii0312
Copy link
Copy Markdown

Aditii0312 commented Aug 17, 2025

am trying to connect mcp server to puch ai several times (through terminal) idk why it is showing MCP Connection failed: session terminated, did they stop hiring??
can anyone help me??
Image 17-08-25 at 7 22 PM

@Aditii0312
Copy link
Copy Markdown

Screenshot (476) How did i find my application was parsed or not? could anyone response to this query. Thank you in advance.

how did u connect your mcp server?

@Akashgite1
Copy link
Copy Markdown

/tool resume use this command to checkout

@Aditii0312
Copy link
Copy Markdown

/tool resume use this command to checkout

my mcp connection is getting failed even after trying several times it is showing as session terminated
any suggestions for that??

@Akashgite1
Copy link
Copy Markdown

did you restart the server...?

@Aditii0312
Copy link
Copy Markdown

is validation after connecting to mcp server mandatory?

@Souhadra
Copy link
Copy Markdown

image is this all?

@SayyedNehaFirdous
Copy link
Copy Markdown

SayyedNehaFirdous commented Aug 21, 2025

Hi @ArjitJ ... Could you please confirm if my application is successful? I'm confused if my application is submitted or not because it's not showing any message like "Your application is submitted." I already tried to ask in Puch chat it's unable to confirm, rather suggesting to contact Puch AI directly. Would be pleased to hear from you...

Screenshot 2025-08-22 004219

@SINGHBP29
Copy link
Copy Markdown

Hi Puch AI Team 👋,

I have set up my MCP server and connected it with Puch using the application key.

  • Server URL: https://2990884d9286.ngrok-free.app/mcp
  • Phone Number: 91XXXXXXXXX
  • Resume Tool: Accepts my local resume, converts it to markdown, and submits it to the Puch MCP endpoint.

Please confirm if my resume submission has been received successfully. 🚀

Thank you 🙏
— Bhanu Pratap Singh

@Ayush25-pl
Copy link
Copy Markdown

/tool resume use this command to checkout

my mcp connection is getting failed, even after trying several times it is showing as session terminated any suggestions for that??

Try reseting it using /reset command and the connect your mcp server before that verify your mobile number in starter code is same as your whatsapp number you are using to chat with Puch AI.

@Epein5
Copy link
Copy Markdown

Epein5 commented Aug 23, 2025

Screenshot from 2025-08-24 02-13-12 I successfully connected to the MCP server and received the message below:
  You have successfully connected to the MCP server.
  You can share your MCP server with others using the following link: https://puch.ai/mcp/QD7k3tbo8T.
  Feel free to use the hashtag #BuildWithPuch in your posts about your MCP.
  Please note that you have not been disconnected from any previous servers. Use the command /mcp list to see all your MCP servers.

Are there any other tasks I need to complete?
Also, please be aware that ngrok will only be active for the next 12 to 20 hours.

@Rajvardhan-singh-26
Copy link
Copy Markdown

image Successfully connected to MCP server. You can share your mcp server with other people by using the link: https://puch.ai/mcp/Zj0yRTanLb Use the hashtag #BuildWithPuch in your posts about your MCP.

Please note that you've not been disconnected from previous servers, if any. Use /mcp list to see all your MCP servers.

@cool-skr
Copy link
Copy Markdown

hello completed the assignment :
image
the ngrok tunnel will only be active for sometime
anything else to complete after this ?

@princekumar01
Copy link
Copy Markdown

Dear Hiring Manager,

I am writing to express my enthusiastic interest in the AI Engineer position at Puch, as advertised on your careers page. Having followed Puch’s innovative work in multilingual AI assistants with great interest, I am confident that my skills and experience align perfectly with your team’s needs.

In my role at Tata Consultancy Services, I gained hands-on experience building and deploying LLM-powered solutions, including a conversational AI chatbot and a claims intelligence platform. I am proficient in LangChain, FastAPI, and Hugging Face Transformers, and I have a strong understanding of RAG and prompt engineering techniques. My project fine-tuning LLaMA 3 demonstrates my commitment to staying at the forefront of AI advancements.

I am particularly drawn to Puch’s focus on serving millions of users across India in multiple languages. I am eager to leverage my skills to contribute to a system that addresses real-world challenges in language and scale.

Thank you for your time and consideration. I have attached my resume for your review and welcome the opportunity to discuss my qualifications further.

Sincerely,

Prince Kumar

@Abhinav210310453045
Copy link
Copy Markdown

Hi I have did the assignment, my mcp server is running , but when I ask Puch AI to provide me my resume it is showing that it is recieving the toll not implemented error,
although my ngrok and mcp server terminal both are giving 200 code in logs
I am not able to get my resume form puch
please help anyone

@Skow3
Copy link
Copy Markdown

Skow3 commented Sep 4, 2025

Just completed the above mentioned steps, It was able to retrieve my Resume markdown but how can i check whether the application has successfully submitted or not?
On '/apply' it is still showing that Application is open please proceed with further steps

@AvichalDwivedi2205
Copy link
Copy Markdown

image image image

Am i donw with the application?

@Harshit0502
Copy link
Copy Markdown

Screenshot 2025-09-05 204300 Hello Does the application is sumbitted ?? image

@aydiegithub
Copy link
Copy Markdown

Hi PuchAI team,

I’ve successfully applied! Running the command below should have sent my resume across to your team:

user_tool_Puch_AI_Resume_Server_resume {}

@malepti
Copy link
Copy Markdown

malepti commented Sep 10, 2025

Hi iam venkatesh, a data scientist, searching for a good career opportunity, I saw the puch ai post I search a lot icn't find the link to apply so I commented. Iam intrested in the opportunity. Connect me through my LinkedIn link

https://www.linkedin.com/in/malepati-venkatesh-7a86921b6/

@Hemasai0352
Copy link
Copy Markdown

Hi team, I am Hemasai , a developer, build a android and ios apps using react native and having hands on experience in html and css and also worked on rest api using c#. I am interested to learn and work in AI to expand my career . I am eagerly waiting to work .
https://www.linkedin.com/in/proddutur-hemasai-0a5059196

@PinnamrajuAbhishek
Copy link
Copy Markdown

My submission:
PuchAI

@Parshav14
Copy link
Copy Markdown

Okay, here's Parshav's resume as provided. It looks like a very impressive profile with strong academic achievements, relevant work experience at Samsung and ISRO, and a good set of technical skills!

Is there anything specific you'd like me to do with this resume? Perhaps you'd like me to:

  • Summarize key skills?
  • Extract specific information (like project details)?
  • Compare it to a job description?
  • Or something else entirely?

🛠 From Tool

Dear Team,
I have successfully submitted my resume. Please check and I am very much interested in internship.
Thank you

@doppaprasad
Copy link
Copy Markdown

@anuxlab
Copy link
Copy Markdown

anuxlab commented Sep 19, 2025

Performed all the steps as per the instructions.

Steps 1, 2, 3:
Screenshot 2025-09-19 at 3 06 33 PM

Step 4:
image

Successfully submitted.

@KingRain
Copy link
Copy Markdown

Hello @ArjitJ and Puch AI Team, Im writing to let you know that I have completed the task mentioned above.
You can reach out to me at samjoe55555@gmail.com
Im attaching screenshots of the same.
Looking forward on hearing back from your team
Thank you
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment