Skip to main content
Glama

post_report

Submit a standup report to Geekbot by providing answers to all standup questions using conversation context.

Instructions

Posts a report to Geekbot. Use this tool to post a report to Geekbot using the context of the conversation. This tool is usually used after the list_standups tool to get the standup id and the question ids. If the context of the conversation lacks sufficient information to answer the questions of the standup, the assistant will ask for the missing information. The report should be beautifully formatted. ALWAYS type formatted reporte in the conversation for preview purposes before calling this tool.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
standup_idYesID of the specific standup to post the report to.
answersYesAn object where keys are the string representation of question IDs and values are objects containing the answer text. All questions of the standup must be included in the object.

Implementation Reference

  • The main handler function that processes answers (escaping HTML via parse_answer_text), calls the GeekbotClient.post_report API, parses the response via posted_report_from_json_response, and returns a success TextContent.
    async def handle_post_report(
        gb_client: GeekbotClient,
        standup_id: int,
        answers: dict[int, dict[str, str]],
    ) -> list[types.TextContent]:
        """Post a report to Geekbot
    
        Args:
            standup_id: int,
            answers: dict[int, dict[str, str]],
        Returns:
            str: Properly formatted JSON string of reports list
        """
        processed_answers_for_api = {}
        for question_id, answer_obj in answers.items():
            processed_answers_for_api[question_id] = {
                "text": parse_answer_text(answer_obj["text"])
            }
        report = await gb_client.post_report(
            standup_id=standup_id,
            answers=processed_answers_for_api,
        )
        parsed_report = posted_report_from_json_response(report)
        return [
            types.TextContent(
                type="text",
                text=f"Report posted successfully: {parsed_report.model_dump()}",
            )
        ]
  • MCP Tool schema definition for 'post_report', defining its name, description, and input JSON schema (requiring standup_id and answers).
    post_report = types.Tool(
        name="post_report",
        description="Posts a report to Geekbot. Use this tool to post a report to Geekbot using the context of the conversation. This tool is usually used after the `list_standups` tool to get the standup id and the question ids. If the context of the conversation lacks sufficient information to answer the questions of the standup, the assistant will ask for the missing information. The report should be beautifully formatted. ALWAYS type formatted reporte in the conversation for preview purposes before calling this tool.",
        inputSchema={
            "type": "object",
            "properties": {
                "standup_id": {
                    "type": "integer",
                    "description": "ID of the specific standup to post the report to.",
                },
                "answers": {
                    "type": "object",
                    "description": "An object where keys are the string representation of question IDs and values are objects containing the answer text. All questions of the standup must be included in the object.",
                    "additionalProperties": {
                        "type": "object",
                        "properties": {
                            "text": {"type": "string"},
                        },
                        "required": ["text"],
                    },
                },
            },
            "required": ["standup_id", "answers"],
        },
    )
  • Registration of the 'post_report' tool: imported from the module, included in list_tools(), and dispatched in run_tool() via a match/case for 'post_report'.
    from geekbot_mcp.tools.post_report import handle_post_report, post_report
    
    
    def list_tools() -> list[types.Tool]:
        return [
            list_members,
            list_standups,
            fetch_reports,
            post_report,
            list_polls,
            fetch_poll_results,
        ]
    
    
    async def run_tool(
        gb_client: GeekbotClient,
        name: str,
        arguments: dict[str, str] | None,
    ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
        match name:
            case "list_members":
                return await handle_list_members(gb_client)
            case "list_standups":
                return await handle_list_standups(gb_client)
            case "fetch_reports":
                return await handle_fetch_reports(gb_client, **arguments)
            case "post_report":
                return await handle_post_report(gb_client, **arguments)
            case "list_polls":
                return await handle_list_polls(gb_client)
            case "fetch_poll_results":
                return await handle_fetch_poll_results(gb_client, **arguments)
            case _:
                raise ValueError(f"Tool {name} not found")
  • Helper function that converts answer text to string if needed and unescapes HTML entities (e.g., ' to ').
    def parse_answer_text(answer_text: any) -> str:
        """Parse the answer text to ensure it's a string and escape HTML characters."""
        if not isinstance(answer_text, str):
            answer_text = str(answer_text)
        return html.unescape(answer_text)
  • API client method that POSTs a report to the Geekbot /reports/ endpoint with standup_id and answers as JSON.
    async def post_report(
        self,
        standup_id: int,
        answers: dict[int, dict[str, str]],
    ) -> dict:
        """Post a report"""
        endpoint = f"{self.base_url}/reports/"
        response = await self._client.post(
            endpoint,
            headers=self.headers,
            json={"standup_id": standup_id, "answers": answers},
        )
        response.raise_for_status()
        return response.json()
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description carries full burden. It discloses the need for preview and handling of missing info, but does not explain success/failure behavior, side effects, or idempotency. Minor typo 'reporte' but not impactful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Description is informative but somewhat verbose with slight redundancy (first two sentences say similar things). Could be more concise while retaining key guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers workflow (list_standups associations, preview requirement, missing info handling) but lacks explanation of expected output or error conditions. Adequate but could be more complete given no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% coverage, baseline 3. Description adds value by explaining that standup_id comes from list_standups and that answers must include all question IDs, beyond the schema's description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Posts a report to Geekbot' and distinguishes from sibling tools (fetch/list operations). It specifies the verb (post) and resource (report), providing unambiguous purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states it is used after `list_standups` to obtain IDs, instructs to ask for missing information, and requires a formatted preview before calling. This provides clear when-to-use and preparatory steps.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

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/geekbot-com/geekbot-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server