# ExcelDashboard AI MCP

Generate editable analytical reports from an analyzed Markdown outline. The Agent reads files and verifies calculations; MCP creates the report and returns a live preview URL.

Documentation reviewed: 2026-10-07. This date records documentation review, not a compatibility test for every client. WorkBuddy connection and report generation were verified in the test environment through existing user tests; the exact tested client version was not recorded. Other clients require end-to-end verification.

- Client setup and troubleshooting: https://www.exceldashboard.ai/mcp/guides
- Synthetic three-page example: https://www.exceldashboard.ai/mcp/examples/agency-report
- SkillHub release: 1.0.0; its package was verified against the canonical Skill on 2026-10-06.

## Read this first

This is the public instruction document, not an authenticated MCP tool response. Read the complete outline reference below before creating a report. Configure and authorize MCP through the current client's supported connection workflow, rather than POSTing to the HTML introduction page from a browser.

If persistent Skill installation is unsupported but the client can connect to MCP, follow the full instructions in this conversation and explain that no persistent installation occurred. If configuration or OAuth is unsupported, give supported manual steps and stop before tool calls. Do not claim a successful connection until tool discovery succeeds.

## Connection

- Endpoint: https://www.exceldashboard.ai/mcp
- Transport: Streamable HTTP
- Authorization: OAuth with browser consent and workspace selection. Never ask the user to paste tokens into chat.
- Published Skill: https://skillhub.cn/skills/org-9c0xwtir/algforce-report-v1
- SkillHub identifier: @org-9c0xwtir/algforce-report-v1; verified release: 1.0.0.
- Official SkillHub installation guide: https://skillhub.cn/install/skillhub.md
- Installation instruction: Follow https://skillhub.cn/install/skillhub.md to install @org-9c0xwtir/algforce-report-v1 from SkillHub (https://skillhub.cn/skills/org-9c0xwtir/algforce-report-v1) in this client's supported skills directory, preserving references/. Determine the correct directory for this Agent. Follow the client's permission requirements and explain unsupported steps. Restart or reload the client if needed. If persistent installation is unsupported, explain that limitation and use the complete instructions from the MCP introduction page for the current conversation instead; do not claim the Skill is installed. Installing the Skill does not configure MCP or complete OAuth.
- CLI command example (after installing SkillHub CLI): skillhub install '@org-9c0xwtir/algforce-report-v1' --dir '/path/to/your/agent/skills'
- Replace /path/to/your/agent/skills with the actual directory supported by the current Agent before executing the command. Reload or restart the client when required.
- Install from SkillHub and preserve references/. This website does not distribute a ZIP package. Merely reading these instructions does not persistently install a Skill or configure MCP.
- Automatic setup depends on client capabilities and permissions. Browser authorization requires the user.
- Tool discovery requires authorization. The client must support remote MCP and the server's OAuth flow.
- Tools: create_report(outline, locale?) and get_report(job_id). No file-upload or report-editing MCP tool is exposed.
- Use the exact returned report_url. Preview and completed shares are public read-only links; anyone with the link can view them. Frontend editing requires separate sign-in and permissions.
- Report creation uses the authorized workspace and its account limits. Do not create a report merely to test connection.

## Client-specific setup

Merge examples into existing configuration. Do not overwrite other servers. The user completes browser consent and workspace selection; installation does not bypass authorization. Never fabricate a successful connection from saved configuration alone.

### WorkBuddy

Connection and report generation verified in our test environment.

Evidence: existing user test records. The exact client version was not recorded; verification does not cover every version.

1. Add the URL below in MCP service management using Streamable HTTP, or merge this JSON into existing configuration without removing other servers.
2. Select authentication, sign in in the browser, choose a workspace, and consent. WorkBuddy manages the callback; no fixed redirect URI or secret is needed.
3. Install the report Skill from SkillHub. If using a connector package, confirm its bundled Skill is loaded. No official one-click connector installation link is published here.
4. Confirm discovery of create_report and get_report. Internal preview requires an available browser tool; otherwise show the clickable report link.

```
{
  "mcpServers": {
    "algforce-reports": {
      "type": "streamableHttp",
      "url": "https://www.exceldashboard.ai/mcp",
      "timeout": 30000
    }
  }
}
```

Official sources: [WorkBuddy Connector](https://open.workbuddy.cn/en/docs/connector).

### Codex

Based on official documentation; not yet tested with this service.

The example uses the CLI. The IDE extension also supports adding the URL in MCP settings and selecting Authenticate.

1. Confirm that the installed version provides codex mcp commands. Inspect any existing server with the same name before changing configuration.
2. Add the server in a terminal and start login; complete browser consent and workspace selection.
3. Load the Skill using the common instructions below and reload the client if needed. In the current session, use /mcp to confirm both tools are available; a saved configuration entry alone is not proof of connection.

```
codex mcp add algforce-reports --url https://www.exceldashboard.ai/mcp
codex mcp login algforce-reports
codex mcp list
```

Official sources: [Codex MCP](https://developers.openai.com/codex/mcp/).

### Claude Code

Based on official documentation; not yet tested with this service.

This example uses user scope for cross-project access. Do not copy the WorkBuddy type field into Claude Code configuration.

1. Add the HTTP server in a terminal. Start Claude Code, enter /mcp, and select the server to authenticate.
2. Complete browser consent and workspace selection, then load the report Skill using the common instructions below.
3. Confirm both tools are available in the current session. If they have not loaded, reconnect or start a new session as the client directs.

```
claude mcp add --transport http --scope user algforce-reports https://www.exceldashboard.ai/mcp
claude mcp list
```

Official sources: [Claude Code MCP](https://code.claude.com/docs/en/mcp).

### Hermes Agent

Based on official documentation; not yet tested with this service.

Merge into mcp_servers in ~/.hermes/config.yaml, preserving existing entries. Remote or SSH deployments need the official callback forwarding workflow; a local browser cannot be assumed to reach a remote loopback listener.

1. Add the OAuth configuration below, then run hermes mcp login algforce-reports in a fresh terminal.
2. Complete browser consent, load the Skill using the common instructions below, and restart or reload the session that will execute the task.
3. Confirm both tools are registered in that session. Do not use device-code login: this service does not advertise a device authorization endpoint.

```
mcp_servers:
  algforce-reports:
    url: "https://www.exceldashboard.ai/mcp"
    auth: oauth
```

Official sources: [Hermes MCP](https://hermes-agent.nousresearch.com/docs/user-guide/features/mcp).

### OpenClaw

Based on official documentation; not yet tested with this service.

For OAuth-capable Gateway/embedded runtimes only; the node-hosted v1 path does not support OAuth. This example is for a single operator. Multi-user deployments require per-requester identity and gateway.publicOrigin as documented by OpenClaw.

1. Confirm that the installed version and runtime support remote OAuth via mcp.servers, then merge this block into existing openclaw.json.
2. Run openclaw mcp login algforce-reports, complete browser consent, and reload the Gateway as required by the client.
3. Load the Skill using the common instructions below. Confirm that the executing Agent can call both tools; saving configuration or logging in does not prove tool loading in every runtime.

```
{
  "mcp": {
    "servers": {
      "algforce-reports": {
        "url": "https://www.exceldashboard.ai/mcp",
        "transport": "streamable-http",
        "auth": "oauth"
      }
    }
  }
}
```

Official sources: [OpenClaw MCP configuration](https://docs.openclaw.ai/gateway/config-extensions), [OpenClaw node-hosted limitations](https://docs.openclaw.ai/nodes/mcp-and-skills).

### Connection-only verification request

Read https://www.exceldashboard.ai/mcp.md and the complete Skill and outline reference. Verify that this session has an authorized MCP connection exposing create_report and get_report. Report any missing setup, Skill loading, or authorization step. Do not create a report, invent a job_id, or claim successful connection from a saved configuration alone.

## Product questions

### Can I use this without persistent Skill installation?

If the client supports MCP but cannot install a Skill, ask the Agent to read the complete English guide here or /mcp.md and follow it in the current conversation. This does not persistently install a Skill; a new conversation may need to read it again. MCP connection and authorization are still required.

### Can my Agent install and connect automatically?

This depends on the client’s file installation, MCP configuration, and browser authorization capabilities. Reading a guide does not install a Skill. First connection still requires you to sign in and select a workspace.

### Do I upload Excel or CSV files to MCP?

Your Agent reads files, analyzes data, and verifies calculations. It sends aggregated chart data and findings in outline. MCP accepts the outline; it does not expose a file-upload tool.

### Where can I view and edit reports?

Creation returns a preview link that updates during generation. The Edit button opens the website editor after sign-in and permission checks. MCP itself has no editing tool.

### Are preview links public?

Yes. Preview and completed share links are public and read-only: anyone with the link can view them. Confirm that the report content is suitable for sharing before creation. Editing permissions are checked separately.

### Which clients are supported?

WorkBuddy connection and report generation have been verified in our test environment. Other clients must support remote Streamable HTTP MCP and the required OAuth flow; compatibility should be tested after setup.

### Does report generation cost anything?

Report creation is subject to the authorized workspace’s account limits and plan. See current pricing on the website. Installing the Skill does not provide unlimited report generation.

### Which tasks and teams is this for?

For agencies, sales operations, and management teams with analyzable data and reporting needs. The Agent verifies inputs and conclusions before report creation; rendering does not replace data validation.

### How does this differ from writing Markdown in an Agent?

Markdown can express a text analysis directly. This service renders an outline with verified data into a visual report, returns progress and a public preview, and offers a website editor for refinement. MCP has no file-upload, editing, or export tool.

### Can MCP directly analyze Excel or CSV files?

MCP accepts outline, not raw files. The current Agent needs file-reading and analysis capabilities to calculate metrics, validate definitions, and place the required aggregates into the outline.

### Synthetic agency example request

Read https://www.exceldashboard.ai/mcp.md and its complete Skill and outline reference. After MCP authorization, use the complete three-page synthetic agency outline provided there to create one English demonstration report. The input is synthetic July-September 2026 data: monthly spend USD 10,000 each; monthly attributed revenue USD 30,000, 35,000, and 40,000; fixed 7-day click attribution. Verify spend USD 30,000, revenue USD 105,000, and quarterly ROAS 3.50x. Clearly label synthetic data, exclude agency fees, organic revenue, and refunds, and do not infer causality. Show the exact returned report_url immediately, retain job_id, and poll get_report serially using poll_after_seconds until completed or failed. This request authorizes one report creation, which is subject to workspace limits. Do not create again to check progress.

This demonstration uses synthetic data, not real client outcomes. Quarterly spend is USD 30,000, attributed revenue is USD 105,000, and ROAS is 3.50x. The complete outline below contains three pages: verified overview, measurement definitions, and findings/actions. The page https://www.exceldashboard.ai/mcp/examples/agency-report is documentation, not a generated report URL. Creating the demonstration is subject to the authorized workspace limits and requires an explicit user request.

## Tool arguments and job handling

- Discover the actual exposed tools first. The client may prefix create_report and get_report with a server name; use the names and schemas actually returned.
- create_report accepts exactly one required string, outline, and one optional string, locale. The default locale is zh-CN; use en when the requested report is English. Do not send title, workspace_id, idempotency_key, or file-upload parameters.
- get_report accepts only job_id, the value returned by create_report. Do not substitute report_id or a preview/share identifier.
- A returned job_id and report_url mean submission succeeded, not that generation has completed. Show the exact report_url immediately. Poll serially according to poll_after_seconds (about 15 seconds while running).
- Only status completed confirms successful generation. Stop polling on completed or failed. Failed results should be explained using error_code and error_message. Completion can still carry a preview/share warning; explain any returned warning rather than inventing a working link.
- Tool responses can carry structuredContent or text content. Inspect isError and parse the returned content using the actual client representation. Do not treat an HTTP 200 alone as report success.
- After a creation timeout, query a known job_id. If no ID was received, submission is uncertain; ask before submitting another creation request. A status query must never trigger another create_report call.
- Use an actual callable client browser/preview tool to open and refresh the same report tab when available. Otherwise show a clickable link and explain that the user must open it. Never claim that an internal preview opened without a successful tool call.
- Keep the returned report_url visible after each status result. The page refreshes its generated content independently; this does not automatically refresh the client's conversation.

## Public OAuth discovery

- Protected resource metadata: https://www.exceldashboard.ai/.well-known/oauth-protected-resource
- Authorization server metadata: https://www.exceldashboard.ai/.well-known/oauth-authorization-server
- Follow the metadata and client OAuth flow; never invent a client ID, a fixed redirect URI, or a client secret. The client manages callback and token handling. Do not ask users to paste credentials into chat.

## MCP tool reference

These are MCP tool arguments, not REST form fields or OAuth parameters. The client invokes tools through tools/call and manages tokens. Examples use synthetic data and fictional job IDs; do not create a report merely to test connection.

### create_report

Purpose: asynchronously create a new report in the authorized workspace. OAuth scope: reports.write. Each call creates a new job.

| Argument | Type | Required | Default | Meaning |
|---|---|---|---|---|
| outline | string | Yes | — | Complete Markdown outline with verified findings, metrics and aggregated chart data; nonempty, at most 1,000,000 UTF-8 bytes. |
| locale | string | No | zh-CN | Report language, for example zh-CN or en. The current interface does not restrict this string to an enum. |

outline must follow the complete reference: # main title, > subtitle, meta information, ## page headings and page layouts. The service extracts the report name from the first nonempty # title (at most 300 UTF-8 bytes) and requires at least one nonempty ## page. Set meta.pages to the actual page count. Do not pass a JSON object or file path as outline.

Do not send title, outline_markdown, workspace_id, idempotency_key, or other extra arguments. The title comes from outline and the workspace comes from OAuth authorization.

#### Complete argument example (synthetic data)

```json
{
  "outline": "# Agency Client Performance Review\n\n> Synthetic demonstration data for July–September 2026; not a real client report.\n\n<!-- meta\ngoal: Review campaign efficiency and agree on next month's priorities\nskill: agency-client-review\nstyle: default\nlang: business\npages: 3\naudience: Client marketing lead\ndate_range: 2026-07-01 to 2026-09-30\ngenerated: 2026-10-05\n-->\n\n---\n\n## Data overview\n`layout: KPI Ledger`\n`layout_intent: Summarize verified quarterly performance before reviewing definitions.`\n`layout_slots: kpi-summary`\n\n- [slot: kpi-summary] Quarterly performance [smart_layout]\n  | Metric | Current value | Description |\n  |---|---|---|\n  | Ad spend | USD 30,000 | Total July–September campaign spend |\n  | Attributed revenue | USD 105,000 | Revenue attributed using the demo's fixed 7-day click window |\n  | ROAS | 3.50x | USD 105,000 / USD 30,000; excludes agency fees |\n  Evidence: Monthly ROAS increased from 3.00x in July to 4.00x in September.\n  Attribution: These aggregates show an efficiency trend, but do not establish its cause.\n  Recommendation: Review channel and campaign breakdowns before reallocating budget.\n\n---\n\n## Data definitions\n`layout: Specification Sheet`\n`layout_intent: Define the source, attribution window and calculation scope.`\n`layout_slots: spec-body`\n\n- [slot: spec-body] Measurement scope [smart_layout]\n  | Definition | Value |\n  |---|---|\n  | Source | Synthetic monthly campaign aggregates for this example |\n  | Scope | July–September 2026; all amounts in USD |\n  | Spend by month | July 10,000; August 10,000; September 10,000 |\n  | Revenue by month | July 30,000; August 35,000; September 40,000 |\n  | ROAS definition | Attributed revenue / ad spend; fixed 7-day click window |\n  Footnote: Agency fees, organic revenue and refunds are excluded. No causal or incremental-lift conclusion can be made from these aggregates.\n\n---\n\n## Validate the efficiency trend before increasing investment\n`layout: Closing Statement`\n`layout_intent: Turn the measured trend into specific next steps without asserting causality.`\n`layout_slots: takeaways`\n\n- [slot: takeaways] Findings and next steps [smart_layout]\n  Findings:\n  01. Quarterly ROAS was 3.50x on USD 30,000 of spend.\n  02. Monthly attributed revenue rose from USD 30,000 to USD 40,000 while spend stayed constant.\n  03. The aggregate data cannot isolate the drivers or confirm incremental revenue.\n  Actions:\n  P1. Marketing lead: validate attribution and refund handling before the next review.\n  P2. Agency analyst: compare channels and campaigns using consistent attribution definitions.\n  P3. Account lead: agree on a controlled budget test after validating the breakdown.\n  Goal: Confirm a repeatable efficiency improvement before scaling spend.\n",
  "locale": "en"
}
```

#### Successful creation data

```json
{
  "job_id": "11111111-1111-4111-8111-111111111111",
  "status": "running",
  "report_url": "https://www.exceldashboard.ai/report/preview/11111111-1111-4111-8111-111111111111?b=report",
  "poll_after_seconds": 15
}
```

| Result field | Type | Meaning |
|---|---|---|
| job_id | string | New job ID. Save it for subsequent status queries. |
| status | string | running at successful submission; this does not prove completion. |
| report_url | string | Public read-only preview URL. Immediately show the exact returned link. |
| poll_after_seconds | integer | Recommended polling interval, currently 15 seconds. |

### get_report

Purpose: read a job created by the current user in the authorized workspace. OAuth scope: reports.read; this tool does not modify reports.

| Argument | Type | Required | Meaning |
|---|---|---|---|
| job_id | string | Yes | The job ID returned by create_report, not report_id, a share ID or a full URL. No default. |

```json
{
  "job_id": "11111111-1111-4111-8111-111111111111"
}
```

#### Complete running result example

```json
{
  "job_id": "11111111-1111-4111-8111-111111111111",
  "operation": "create",
  "status": "running",
  "stage": "generating",
  "completed_pages": 1,
  "pages_started": 2,
  "total_pages": 3,
  "report_id": null,
  "report_url": "https://www.exceldashboard.ai/report/preview/11111111-1111-4111-8111-111111111111?b=report",
  "share_url": null,
  "poll_after_seconds": 15,
  "error_code": null,
  "error_message": null
}
```

| Result field | Type | Meaning |
|---|---|---|
| job_id | string | The queried job ID. |
| operation | string | create for jobs created by this connector. |
| status | string | running: keep tracking; completed: generation finished; failed: stop and explain the failure. |
| stage | string | Backend stage label; do not assume a fixed stage enum or infer a percentage from it. |
| completed_pages | integer | Completed page count reported by the backend. |
| pages_started | integer | Started progress count while generating; not completed pages, and can be 0 after the job ends. |
| total_pages | integer | Total pages counted from the outline’s ## headings. |
| report_id | string or null | Report resource ID, possibly null while generating; never substitute it for get_report.job_id. |
| report_url | string | Report preview entry point, also returned while running; its existence does not prove completion. |
| share_url | string or null | Underlying public share URL after completion, possibly null. Prefer report_url in user replies. |
| poll_after_seconds | integer or null | Currently 15 seconds while running; null when the job ends. |
| error_code | string or null | Job error or share-preparation warning code; null when absent. |
| error_message | string or null | Associated error or warning description. |

Stop polling immediately on completed or failed. Successful generation can still carry a share-preparation warning; explain it. After a creation timeout, query the original job when its ID is known. Without an ID, submission is uncertain: ask before recreating.

### MCP result envelope and errors

The examples above are business result data. Actual successful MCP tool results include structuredContent and content[0].text (the JSON-encoded business data), with isError false. Prefer the client’s structured result and do not rely only on HTTP status.

```json
{
  "isError": true,
  "structuredContent": {
    "error_code": "INVALID_ARGUMENT",
    "message": "Invalid create_report arguments"
  },
  "content": [
    {
      "type": "text",
      "text": "INVALID_ARGUMENT: Invalid create_report arguments"
    }
  ]
}
```

| Failure | Meaning and recovery |
|---|---|
| INVALID_ARGUMENT | Invalid arguments or outline; correct them using the actual error message. |
| NOT_FOUND | Job absent or inaccessible to the current user/workspace; check the original job ID and authorization. |
| SERVER_ERROR | Service could not create or read a job; do not automatically recreate an uncertain submission. |
| HTTP 401 | Missing or invalid token; reauthorize through the client. |
| HTTP 403 | Insufficient scope; follow WWW-Authenticate and authorize the required scope. |
| status: failed | The status query succeeded but generation failed; read error_code/error_message and stop polling. |


## Complete Skill

---
name: algforce-report
description: Analyze user-provided data or a report topic, prepare an AlgForce report outline, and create and track the report through the AlgForce MCP tools. Use when a user asks for an AlgForce data analysis report or wants to track one.
---

# AlgForce Data Analysis Reports

Use the current client's file-reading, computation, and web-search capabilities to complete the analysis. AlgForce generates reports from the resulting outline. This Skill orchestrates only two MCP tools: `create_report` and `get_report`.

These instructions are written in English. User-facing replies and report content should follow the user's requested language; the instruction language does not require English report content.

## Tool Contract

| Tool | Parameters | Result |
| --- | --- | --- |
| `create_report` | Required `outline`: a nonempty Markdown string following the outline reference. Optional `locale`: a string, default `zh-CN`. | `job_id`, `status: "running"`, `report_url`, and `poll_after_seconds`. |
| `get_report` | Required `job_id`: the string returned by creation. | `status`, `stage`, page counts, `report_url`, and completion or failure details. |

Create using `{"outline":"<complete Markdown following references/outline-format.md>","locale":"en"}`. The outline text in this example is a placeholder: replace it with the complete analyzed report outline. Query using `{"job_id":"<returned job_id>"}` and replace the placeholder with the actual returned value.

A creation result has the form `{"job_id":"<job UUID>","status":"running","report_url":"<actual preview URL>","poll_after_seconds":15}`. Status results also include `operation`, `stage`, `completed_pages`, `pages_started`, `total_pages`, `report_id`, `share_url`, `error_code`, and `error_message`; some values can be null. `poll_after_seconds` is null after the job ends. Only `completed` proves success; `failed` ends tracking with an error. Do not call an editing tool: none is exposed by this connector.

Invalid parameters return a tool error with `error_code: "INVALID_ARGUMENT"` and `message`. Correct the parameters before retrying. After a creation timeout, use the known job ID if one was returned; if no ID was received, explain that submission is uncertain and ask before creating another job.

## Analysis and Outline

1. Determine the audience, business question, time range, metrics, grouping, and intended decision from the user's goal. Ask when an essential metric definition is missing; make explicit assumptions for other details when supported by the files. If the user requests analysis only, deliver the analysis without calling the report creation tool.
2. Read user-uploaded files through the current client. Check field meanings, record grain, time ranges, units, missing values, and duplicates. Use available computation tools for aggregation, comparisons, trends, and relevant group analysis. Verify the baseline, denominator, and sample scope for year-over-year or period-over-period calculations. Search the web only when external context is needed, and record sources and dates. Explain data limitations rather than inventing values or causes.
3. Build a narrative from question and definitions to key findings, evidence and possible causes, and recommendations. Include verified metrics, units, time ranges, and aggregated chart data in `outline`; do not upload raw detail files. Put sources, definitions, and uncertainty on the relevant outline pages. No separate `evidence` field is needed.
4. Before creating a report, write the complete outline according to [references/outline-format.md](references/outline-format.md) and check its format, numbers, and charts. The report name is extracted automatically from the outline's `# Main title`. Briefly explain the analysis approach and planned report if useful. When the user has already requested report creation, do not add a separate outline approval step.

## Creation and Tracking

1. Use the workspace selected on the OAuth consent page for the current connection. Tool calls do not require `workspace_id`. If the connection is unauthorized, ask the user to connect AlgForce in the client and select a workspace. Switching workspaces requires authorization again. Do not ask users to send tokens or workspace IDs in the conversation.
2. Call `create_report` with the complete `outline` and, when needed, `locale` (default: `zh-CN`). Each call submits a new job; do not automatically retry creation. Save the returned `job_id` and immediately show the returned `report_url` as a "View report" link. If a callable built-in browser tool is available, open this URL before the first `get_report` call and save the tab identifier; do not wait until completion to open it. If no such tool exists or opening fails, explain this and continue tracking the job. AlgForce automatically creates a public read-only share when generation completes; users do not need to share manually in the frontend. The preview's Edit button separately verifies the signed-in account and editing permissions.
3. Query status with `get_report({"job_id":"..."})`. Within the client's available execution time, poll serially using the returned `poll_after_seconds`, or approximately 15 seconds if absent. Do not query the same job concurrently. Report actual progress using `stage`, `completed_pages`, `pages_started`, and `total_pages`; do not invent percentages. After every `get_report` result, update the user-visible progress and refresh the same built-in browser tab, keeping the returned preview link in the update. If the client cannot keep waiting, give the user the `job_id` and preview link. The page updates its own progress; resume by querying the existing job next time rather than creating the same report again.
4. Check `status` and `report_url` after each `get_report` result. When `status` is `completed`, stop polling immediately, present the link using the rules below. Do not continue saying that report generation is pending. When `status` is `failed`, explain `error_code` and `error_message`; submit a new job only if regeneration is needed after the cause has been addressed. Status queries do not modify the job.

## Presenting Reports in the Client

- Show the report entry point in a user-visible reply in WorkBuddy or another client. Do not leave the link only in tool results, internal reasoning, or JSON.
- Apply the same presentation rules at creation, during generation, and after completion. Consistently display the returned `report_url` as a "View report" link. Do not replace the original preview entry point with `share_url`, generated HTML, or a local file after completion.
- After creation, discover and use the built-in browser or web-preview tools actually available in the current client to open the returned `report_url` in the results area. Save the tab or page identifier after the first successful open. Refresh or update that same page after every `get_report` result, including completion. Do not repeatedly create tabs or substitute system-browser commands.
- Open and refresh internally only when the client provides the required tools. Follow their actual schemas; do not invent tool names or private URL schemes. If no callable built-in browser tool exists or execution fails, explain this and retain a clickable link. WorkBuddy users can right-click the link and choose the option to open it internally, or set Settings > General > Link opening behavior to always use the built-in browser. These settings determine where clicked links open; they do not let MCP automatically open tabs.
- The page automatically updates generated report content every 5 seconds, independently of Agent polling. It shows a waiting message before the first page is generated. Do not describe a running report as completed.
- Prefer `report_url`, which includes the editing entry point. `share_url` is the underlying read-only `/share/iframe/<share_id>?b=report` share address; provide it separately only when the user requests sharing or embedding. Use the exact returned URL without inserting spaces or rewriting it.
- When `get_report` returns a nonempty HTTP/HTTPS `report_url`, use the original returned URL in a Markdown link. At completion, reply with the equivalent of "Report generated: [View report](actual report_url)" in the user's language. If the report title is known, it may be used as the link label. `actual report_url` is an explanatory placeholder and must be replaced with the real returned URL.
- If the backend returns a valid `report_url` during generation, include "[View report](actual report_url)" in progress updates and state that generation is still in progress. Claim completion only when `status` is `completed`; the existence of a link does not prove completion.
- If `report_url` is empty, show only actual progress. Do not construct a link from `job_id`, `report_id`, or a domain. If the job has completed without a link, explain that the report is complete but the service did not return an opening link, retain the job ID for investigation, and stop waiting for generation.
- Claim that the report has opened inside the client only after actually calling the built-in browser tool and confirming success. If no call was made or it failed, provide the clickable entry point and explain that the user needs to open it; do not claim automatic display.

## Editing Through the Frontend

MCP does not provide a report editing tool. If the user requests changes to an existing report, provide its returned `report_url` and direct them to the preview's Edit button. The frontend verifies the signed-in account and editing permissions before opening the editor. Do not invent an editing tool or silently create a replacement report. Create a new report only when the user requests a separate report.

## Error Recovery

- `NOT_FOUND`: distinguish `job_id` from `report_id`, then check the current user's access and workspace permissions.
- Authorization failure: guide the user to reconnect AlgForce in the current client. Do not request or display tokens.
- Job failure or timeout: query the existing `job_id` first to confirm its final status. Submit a new creation job only after failure is confirmed and its cause has been addressed.


## Complete outline reference

# AlgForce Report Outline Format

Use this reference to prepare `create_report.outline`. It is based on the project's report Skill outline format and Default layout specifications. It defines page syntax and available layouts, rather than prescribing a fixed number or sequence of analysis pages. Choose pages according to the report goal, audience, and verified data.

## Document and Page Syntax

Start the outline with a `# ` main title, followed by a nonempty `> ` subtitle and a `<!-- meta ... -->` block. Start each page with a `## ` heading and separate pages with `---`. Set `meta.pages` to the actual number of `## ` page headings. Do not add page numbers to page titles.

```markdown
# Report title

> Scope, subject, or central topic

<!-- meta
goal: Goal of this report
skill: Report type
style: default
lang: business
pages: Actual page count
audience: Intended audience
date_range: Actual start and end dates
generated: Generation date
-->

---

## Page title
`layout: English layout name from the table below`
`layout_intent: Reason for selecting this layout`
`layout_slots: Slot names defined for this layout`

- [slot: A slot name declared above] Component title [chart: line]
  | Actual time field | Actual metric field |
  |---|---|
  | Actual period | Actual value and unit |
  - [hint: Annotation supported by the actual data]
```

This example illustrates syntax, not a complete report template. Replace all explanatory text with actual content before submission; do not leave placeholders. Write page-level `layout`, `layout_intent`, and `layout_slots` using the single-line backtick format above. Each main content bullet's `[slot: ...]` must appear in `layout_slots`. Match the number of bullets to the selected layout. Layouts without main content slots must not include content bullets. For `[text]` slots, provide final copy; for `[smart_layout]`, provide structured content; for `[chart: ...]`, provide verified data that can be plotted.

Include a data overview, data definitions, analysis, and a closing decision. Use "Data overview" on page 1 to present the core findings and "Data definitions" on page 2 to explain sources, scope, definitions, and trustworthiness. Use the final page to consolidate findings and actions. Determine the number, sequence, titles, and layouts of intermediate analysis pages from the analysis itself. Prefer conclusion-based titles for analysis pages.

## Layout Selection

Write the layout name in `layout:`. One bullet represents one main content slot, not an additional chart. Use meaningful slot names such as `main-chart`, `left-chart`, `right-chart`, `spec-body`, and `takeaways`; avoid generic names such as `slot1`.

| Layout | Appropriate content and structure | Main content slots |
|---|---|---:|
| `KPI Ledger` | Core metric overview with verified KPIs and three lower-section conclusions: evidence, attribution, and recommendation. Each KPI includes its name, current value, and description. | 1 |
| `Specification Sheet` | Sources, dates, metric definitions, units, and limitations. Use a two-column specification table with at most 5 body rows; put additional details in footnotes. | 1 |
| `Single-Chart Insight` | One main chart supporting one conclusion, with three lines for evidence, attribution, and recommendation. Use `chart`. | 1 |
| `Dual-Chart Comparison` | Two complementary charts on the same topic, with two lines for evidence and risk. Place one `chart` on each side. | 2 |
| `Dual-Track Comparison` | A/B or before-and-after comparison using matching dimensions and definitions. Mirror the factual panels, each with a main metric and brief supporting facts. | 2 |
| `Closing Statement` | Final-page findings and priority actions in two columns, with 2-3 items each and no more than 3. Number findings 01-03 and actions P1-P3; include a "Goal:" line at the bottom. | 1 |
| `Horizontal Timeline` | A linear process with 4-7 steps. Use one timeline component; each node includes its number, key value or status, and stage name. | 1 |
| `Feedback Loop` | A closed cycle with 3-5 steps. Do not use it for a linear process. | 1 |
| `Three Forces Cards` | Three comparable drivers or growth opportunities, each with a short title and one explanatory sentence. | 3 |
| `Three-Column Argument` | A progressive argument across three columns, each supported by facts or data. Use `chart`. | 3 |
| `Four-Column Features` | Four equally weighted features or actions with matching structure. | 4 |
| `Six-Cell Definition` | Six equally weighted definitions, snapshots, or metrics, each with a short title and description. | 6 |
| `Micro-Card Briefing` | Six short observations or tips in a 3-by-2 grid. Each item includes a brief conclusion and footnote. | 6 |
| `Matrix Overview` | An overview of 8-12 comparable items, with a total or overall assessment below. | 8-12 |
| `System Architecture` | A strictly nested three-layer Core / Middle / Outer architecture. Do not use it for an ordinary list. | 1 |
| `Image Hero` | One real image used as evidence, with an explanation or supporting KPI. Do not use it without an actual image. | 1 |
| `Minimal Statement` | A single central claim or section opening. Do not use it for data charts. | 0 |
| `Dot-Matrix Statement` | A qualitative statement or section transition with brief anchor text. Do not use it for data charts. | 0 |
| `Statement Banner` | An intermediate claim with supporting explanation. Do not use it as a substitute for the final decision page. | 0-1 |

For analysis pages with verified quantitative data, consider `Single-Chart Insight` or `Dual-Chart Comparison` first. Choose another layout when the content does not fit. Content in multiple slots should complement rather than repeat the same data. Use `chart` for chart-based layouts and prefer `smart_layout` for processes, matrices, and comparisons. Do not invent metrics, images, or items to fill a layout.

## Charts and Values

Supported chart types are `line`, `bar`, `column`, `grouped_bar`, `stacked_bar`, `grouped_column`, `stacked_column`, `pie`, `donut`, `combo`, `scatter`, and `bubble`. Immediately follow each `[chart: ...]` bullet with a Markdown table whose headers use actual business field names. Ordinary charts use a dimension and metric; grouped charts add a series field; `combo` uses separate columns for the bar and line metrics; scatter charts use X/Y; bubble charts add size. Table-based `smart_layout` content also requires column headers. Preserve units, dates, currencies, and percentage definitions in the data rows. Include only aggregated plotting data, not raw detail records.

After a chart's data rows, include a meaningful `[hint: ...]` to annotate a target line, average, unusual period, or important series or category. Do not add hints to `smart_layout`. Do not present unverified causes as facts. Explain missing data and conflicting definitions on the definitions page or the relevant analysis page. Before submission, verify that page counts, slot counts, chart fields, values, and conclusions are consistent.


## Complete three-page demo outline

The following example uses synthetic data. Submit it only when the user requests a demonstration report.

# Agency Client Performance Review

> Synthetic demonstration data for July–September 2026; not a real client report.

<!-- meta
goal: Review campaign efficiency and agree on next month's priorities
skill: agency-client-review
style: default
lang: business
pages: 3
audience: Client marketing lead
date_range: 2026-07-01 to 2026-09-30
generated: 2026-10-05
-->

---

## Data overview
`layout: KPI Ledger`
`layout_intent: Summarize verified quarterly performance before reviewing definitions.`
`layout_slots: kpi-summary`

- [slot: kpi-summary] Quarterly performance [smart_layout]
  | Metric | Current value | Description |
  |---|---|---|
  | Ad spend | USD 30,000 | Total July–September campaign spend |
  | Attributed revenue | USD 105,000 | Revenue attributed using the demo's fixed 7-day click window |
  | ROAS | 3.50x | USD 105,000 / USD 30,000; excludes agency fees |
  Evidence: Monthly ROAS increased from 3.00x in July to 4.00x in September.
  Attribution: These aggregates show an efficiency trend, but do not establish its cause.
  Recommendation: Review channel and campaign breakdowns before reallocating budget.

---

## Data definitions
`layout: Specification Sheet`
`layout_intent: Define the source, attribution window and calculation scope.`
`layout_slots: spec-body`

- [slot: spec-body] Measurement scope [smart_layout]
  | Definition | Value |
  |---|---|
  | Source | Synthetic monthly campaign aggregates for this example |
  | Scope | July–September 2026; all amounts in USD |
  | Spend by month | July 10,000; August 10,000; September 10,000 |
  | Revenue by month | July 30,000; August 35,000; September 40,000 |
  | ROAS definition | Attributed revenue / ad spend; fixed 7-day click window |
  Footnote: Agency fees, organic revenue and refunds are excluded. No causal or incremental-lift conclusion can be made from these aggregates.

---

## Validate the efficiency trend before increasing investment
`layout: Closing Statement`
`layout_intent: Turn the measured trend into specific next steps without asserting causality.`
`layout_slots: takeaways`

- [slot: takeaways] Findings and next steps [smart_layout]
  Findings:
  01. Quarterly ROAS was 3.50x on USD 30,000 of spend.
  02. Monthly attributed revenue rose from USD 30,000 to USD 40,000 while spend stayed constant.
  03. The aggregate data cannot isolate the drivers or confirm incremental revenue.
  Actions:
  P1. Marketing lead: validate attribution and refund handling before the next review.
  P2. Agency analyst: compare channels and campaigns using consistent attribution definitions.
  P3. Account lead: agree on a controlled budget test after validating the breakdown.
  Goal: Confirm a repeatable efficiency improvement before scaling spend.

