Skip to main content
Glama

Submit a draft

submit_draft
Idempotent

Requires a TechFabric engineer's Microsoft sign-in (scope blog.write). File a post (or, with kind "case-study", a case study) under the engineer's byline, exactly as written: the site builds its preview and emails it to them. Send the whole Markdown with frontmatter (title and description at least), the engineer's own words as sources, and brief_id when it comes from get_brief, or from_idea when it continues an idea they emailed. Lint it clean first. Returns the draft's id and text_hash; next, check_draft with the id. Never publishes.

Input Schema

NameRequiredDescriptionDefault
kindNoWhat the draft is: "post" (the default, a blog post) or "case-study" (content/case-studies, at /case-studies/<slug>). A case study's frontmatter is title, description, sector, stack, track (ai, migration or other) and client when the client register approves naming them or the engineer says the client agreed (client_confirmed); its body opens with ## Challenge, ## Strategy, ## Solution and ## Results, each with a bold one-line statement first. See the editorial_rules resource.post
titleYesThe post's working title
imagesNo
sourcesNoThe engineer's own words the draft's claims come from, as text. For a post: what the engineer told you about their own work (what they built, measured, saw and decided, and any result, client or number they gave you), quoted as they said it, and their notes; the fact-check treats these as the author's own account of the work, so a first-hand sentence they don't back is a finding. Never write them yourself: ask the engineer. For a case study: the engineer's own notes and the project's records (README, changelog, metrics they gave you) its numbers come from. Every number in the case study is checked against these; one that isn't here is a finding. A source is not an approval: a client's metric also needs the client register's approval. Ask the engineer for outcome numbers; never invent them. At most 100,000 characters.
brief_idNoThe brief_id get_brief returned, when the post is from today's brief: it marks the brief done
markdownYesThe whole post, with its frontmatter (title, description at least): it becomes the draft as sent
from_ideaNoThe id of an idea the engineer emailed that is waiting for their own agent (get_status says so): the post continues it, and that idea is closed in its favour
post_typeNoThe post type, which sets the opening rule and how hard the fact-check reads it. story (the default): work someone at TechFabric did. The opening has TechFabric doing that work by paragraph two, and every claim gets the full fact-check. perspective: a talk or conference the author attended, a conversation with an industry leader, others' work, or our view of what's possible. TechFabric's view by paragraph two ("we think", "we'd", "I believe" count). What a speaker or another company said is attributed in the sentence ("In her demo, ...") and must match what the author provided; forward-looking views need no source. whats-new: a new feature in AI, Databricks or related tech, and how it could help future projects. Open on what changed (its date and source), then our view. Product facts (name, preview or GA, date, what it does) are checked against the vendor's docs or release notes; forward-looking views need no source. personal: the author's own essay or position, in the first person, about where the work or the industry is going and what people should do. Opening and fact-check as perspective, and the only type that may take the memo register: conviction carried as "I believe" and the reader addressed as "you" throughout, up to three bold thesis sentences, one "this is not X" thesis reframe and a closing call to act (other types keep every slop rule, though a perspective opening may still state its view as "we think" or "I believe"). Never for an engineer explaining a feature or their own project. Choose personal only when the engineer writes in their own voice about a position, never for an engineer explaining a feature or their project. Left out, it is story; an explainer is always whats-new. Not for a case study.
first_handNoFirst-hand claims only the engineer can source, which the fact-check flagged first_hand (first_hand_to_confirm): each the sentence exactly as quoted, with what it rests on. Sending it asks the engineer; it never confirms anything on your word. check_draft asks them in their client (an elicitation) where it can, otherwise answers with a question and a one-time confirmation: ask them that question, and only if they say yes, send it back as first_hand_confirmation with the same first_hand. submit_draft and update_draft answer with the question and confirmation too, which come back on check_draft with the id. Never a client's result: a number about a client needs the client's confirmation, as a source.
from_idea_notesNoWith from_idea: the author_notes_hash get_status returned for it, so an email they sent since is never closed unread
client_confirmedNoOnly when the engineer tells you they have the client's confirmation to name the client this draft names (its client:, or a client in its text the register doesn't approve). Recorded under the engineer's name with the draft and its text; never send it on your own judgement. It covers naming the client, not results: numbers still need sources.

Output Schema

NameRequiredDescriptionDefault
idYesThe draft's id: every other draft tool takes it
kindNo
nextYes
stateYes
stepsNoWhere the draft is, step by step (the same steps the progress notifications name): done, active (under way now), pending or failed
statusNo
duplicateNo
from_ideaNoWith from_idea: the emailed idea this continues, and whether it was closed in its favour (if not, note says what to do)
post_typeNoThe post type the draft carries (postType in its frontmatter; story when it has none). Not for a case study
text_hashNoThe submitted text's sha256. Filing adds author, date and draft to the frontmatter, so the first update_draft takes draft.base_hash from get_status
first_handNoWhen first_hand was sent: nothing is recorded here. The engineer is asked on check_draft with the id (in their client, where it can ask them), or, for update_draft in a client that can't, this carries the question and a one-time confirmation to hand back on check_draft only after they say yes
editor_linkNo
next_actionYesThe one next step. Do what instruction says; call is the tool and the arguments the server already knows
preview_urlNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / post_type / description
      Previous value: -"The post type, which sets the opening rule and how hard the fact-check reads it. story (the default): work someone at TechFabric did. The opening has TechFabric doing that work by paragraph two, and every claim gets the full fact-check. perspective: a talk or conference the author attended, a conversation with an industry leader, others' work, or our view of what's possible. TechFabric's view by paragraph two (\"we think\", \"we'd\", \"I believe\" count). What a speaker or another company said is attributed in the sentence (\"In her demo, ...\") and must match what the author provided; forward-looking views need no source. whats-new: a new feature in AI, Databricks or related tech, and how it could help future projects. Open on what changed (its date and source), then our view. Product facts (name, preview or GA, date, what it does) are checked against the vendor's docs or release notes; forward-looking views need no source. personal: the author's own essay or position, in the first person, about where the work or the industry is going and what people should do. Opening and fact-check as perspective, and the only type that may say \"I believe\", address the reader as \"you\", bold up to three thesis sentences, make one \"this is not X\" thesis reframe and close on a call to act. Never for an engineer explaining a feature or their own project. Choose personal only when the engineer writes in their own voice about a position, never for an engineer explaining a feature or their project. Left out, it is story; an explainer is always whats-new. Not for a case study."New value: +"The post type, which sets the opening rule and how hard the fact-check reads it. story (the default): work someone at TechFabric did. The opening has TechFabric doing that work by paragraph two, and every claim gets the full fact-check. perspective: a talk or conference the author attended, a conversation with an industry leader, others' work, or our view of what's possible. TechFabric's view by paragraph two (\"we think\", \"we'd\", \"I believe\" count). What a speaker or another company said is attributed in the sentence (\"In her demo, ...\") and must match what the author provided; forward-looking views need no source. whats-new: a new feature in AI, Databricks or related tech, and how it could help future projects. Open on what changed (its date and source), then our view. Product facts (name, preview or GA, date, what it does) are checked against the vendor's docs or release notes; forward-looking views need no source. personal: the author's own essay or position, in the first person, about where the work or the industry is going and what people should do. Opening and fact-check as perspective, and the only type that may take the memo register: conviction carried as \"I believe\" and the reader addressed as \"you\" throughout, up to three bold thesis sentences, one \"this is not X\" thesis reframe and a closing call to act (other types keep every slop rule, though a perspective opening may still state its view as \"we think\" or \"I believe\"). Never for an engineer explaining a feature or their own project. Choose personal only when the engineer writes in their own voice about a position, never for an engineer explaining a feature or their project. Left out, it is story; an explainer is always whats-new. Not for a case study."
  2. Changed2 schema fields changed
    • addedInput schema / properties / post_type
      Added value: +{
      +  "description": "The post type, which sets the opening rule and how hard the fact-check reads it. story (the default): work someone at TechFabric did. The opening has TechFabric doing that work by paragraph two, and every claim gets the full fact-check. perspective: a talk or conference the author attended, a conversation with an industry leader, others' work, or our view of what's possible. TechFabric's view by paragraph two (\"we think\", \"we'd\", \"I believe\" count). What a speaker or another company said is attributed in the sentence (\"In her demo, ...\") and must match what the author provided; forward-looking views need no source. whats-new: a new feature in AI, Databricks or related tech, and how it could help future projects. Open on what changed (its date and source), then our view. Product facts (name, preview or GA, date, what it does) are checked against the vendor's docs or release notes; forward-looking views need no source. personal: the author's own essay or position, in the first person, about where the work or the industry is going and what people should do. Opening and fact-check as perspective, and the only type that may say \"I believe\", address the reader as \"you\", bold up to three thesis sentences, make one \"this is not X\" thesis reframe and close on a call to act. Never for an engineer explaining a feature or their own project. Choose personal only when the engineer writes in their own voice about a position, never for an engineer explaining a feature or their project. Left out, it is story; an explainer is always whats-new. Not for a case study.",
      +  "enum": [
      +    "story",
      +    "perspective",
      +    "whats-new",
      +    "personal"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / post_type
      Added value: +{
      +  "description": "The post type the draft carries (postType in its frontmatter; story when it has none). Not for a case study",
      +  "enum": [
      +    "story",
      +    "perspective",
      +    "whats-new",
      +    "personal"
      +  ],
      +  "type": "string"
      +}
  3. Changed1 schema field changed
    • addedOutput schema / properties / steps
      Added value: +{
      +  "description": "Where the draft is, step by step (the same steps the progress notifications name): done, active (under way now), pending or failed",
      +  "items": {
      +    "properties": {
      +      "id": {
      +        "type": "string"
      +      },
      +      "label": {
      +        "type": "string"
      +      },
      +      "state": {
      +        "enum": [
      +          "done",
      +          "active",
      +          "pending",
      +          "failed"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "id",
      +      "label",
      +      "state"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  4. Changed3 schema fields changed
    • addedInput schema / properties / from_idea
      Added value: +{
      +  "description": "The id of an idea the engineer emailed that is waiting for their own agent (get_status says so): the post continues it, and that idea is closed in its favour",
      +  "type": "string"
      +}
    • addedInput schema / properties / from_idea_notes
      Added value: +{
      +  "description": "With from_idea: the author_notes_hash get_status returned for it, so an email they sent since is never closed unread",
      +  "type": "string"
      +}
    • addedOutput schema / properties / from_idea
      Added value: +{
      +  "description": "With from_idea: the emailed idea this continues, and whether it was closed in its favour (if not, note says what to do)",
      +  "properties": {
      +    "closed": {
      +      "type": "boolean"
      +    },
      +    "id": {
      +      "type": "string"
      +    },
      +    "note": {
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "id",
      +    "closed"
      +  ],
      +  "type": "object"
      +}
  5. Changed2 schema fields changed
    • addedInput schema / properties / first_hand
      Added value: +{
      +  "description": "First-hand claims only the engineer can source, which the fact-check flagged first_hand (first_hand_to_confirm): each the sentence exactly as quoted, with what it rests on. Sending it asks the engineer; it never confirms anything on your word. check_draft asks them in their client (an elicitation) where it can, otherwise answers with a question and a one-time confirmation: ask them that question, and only if they say yes, send it back as first_hand_confirmation with the same first_hand. submit_draft and update_draft answer with the question and confirmation too, which come back on check_draft with the id. Never a client's result: a number about a client needs the client's confirmation, as a source.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "basis": {
      +        "description": "measured: we measured or ran it; our_product: how our own product works; client_told_us: what a client said (not their numbers); customers_ask: what our customers ask; we_did_it: what we built, saw or decided; own_work: first-hand, from the engineer's own work",
      +        "enum": [
      +          "measured",
      +          "our_product",
      +          "client_told_us",
      +          "customers_ask",
      +          "we_did_it",
      +          "own_work"
      +        ],
      +        "type": "string"
      +      },
      +      "claim": {
      +        "description": "The sentence, exactly as the fact-check quoted it",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "claim",
      +      "basis"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 10,
      +  "type": "array"
      +}
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "https://json-schema.org/draft/2020-12/schema",
      +  "properties": {
      +    "duplicate": {
      +      "type": "boolean"
      +    },
      +    "editor_link": {
      +      "type": "null"
      +    },
      +    "first_hand": {
      +      "description": "When first_hand was sent: nothing is recorded here. The engineer is asked on check_draft with the id (in their client, where it can ask them), or, for update_draft in a client that can't, this carries the question and a one-time confirmation to hand back on check_draft only after they say yes",
      +      "type": "object"
      +    },
      +    "id": {
      +      "description": "The draft's id: every other draft tool takes it",
      +      "type": "string"
      +    },
      +    "kind": {
      +      "type": "string"
      +    },
      +    "next": {
      +      "type": "string"
      +    },
      +    "next_action": {
      +      "description": "The one next step. Do what instruction says; call is the tool and the arguments the server already knows",
      +      "properties": {
      +        "action": {
      +          "enum": [
      +            "interview",
      +            "outline",
      +            "approve",
      +            "lint",
      +            "rewrite",
      +            "save",
      +            "submit",
      +            "verify",
      +            "wait",
      +            "answer",
      +            "confirm",
      +            "publish",
      +            "report",
      +            "done",
      +            "stop"
      +          ],
      +          "type": "string"
      +        },
      +        "call": {
      +          "properties": {
      +            "arguments": {
      +              "type": "object"
      +            },
      +            "tool": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "tool",
      +            "arguments"
      +          ],
      +          "type": "object"
      +        },
      +        "instruction": {
      +          "type": "string"
      +        },
      +        "rounds": {
      +          "properties": {
      +            "max": {
      +              "type": "integer"
      +            },
      +            "round": {
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "round",
      +            "max"
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "action",
      +        "rounds",
      +        "instruction"
      +      ],
      +      "type": "object"
      +    },
      +    "preview_url": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "state": {
      +      "type": "string"
      +    },
      +    "status": {
      +      "type": "string"
      +    },
      +    "text_hash": {
      +      "description": "The submitted text's sha256. Filing adds author, date and draft to the frontmatter, so the first update_draft takes draft.base_hash from get_status",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "id",
      +    "state",
      +    "next_action",
      +    "next"
      +  ],
      +  "type": "object"
      +}
  6. Changed1 schema field changed
    • changedInput schema / properties / sources / description
      Previous value: -"A case study only: the engineer's own notes and the project's records (README, changelog, metrics they gave you) its numbers come from, as text, at most 100,000 characters. Every number in the case study is checked against these; one that isn't here is a finding. A source is not an approval: a client's metric also needs the client register's approval. Ask the engineer for outcome numbers; never invent them."New value: +"The engineer's own words the draft's claims come from, as text. For a post: what the engineer told you about their own work (what they built, measured, saw and decided, and any result, client or number they gave you), quoted as they said it, and their notes; the fact-check treats these as the author's own account of the work, so a first-hand sentence they don't back is a finding. Never write them yourself: ask the engineer. For a case study: the engineer's own notes and the project's records (README, changelog, metrics they gave you) its numbers come from. Every number in the case study is checked against these; one that isn't here is a finding. A source is not an approval: a client's metric also needs the client register's approval. Ask the engineer for outcome numbers; never invent them. At most 100,000 characters."
  7. Changed2 schema fields changed
    • addedInput schema / properties / client_confirmed
      Added value: +{
      +  "description": "Only when the engineer tells you they have the client's confirmation to name the client this draft names (its client:, or a client in its text the register doesn't approve). Recorded under the engineer's name with the draft and its text; never send it on your own judgement. It covers naming the client, not results: numbers still need sources.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / kind / description
      Previous value: -"What the draft is: \"post\" (the default, a blog post) or \"case-study\" (content/case-studies, at /case-studies/<slug>). A case study's frontmatter is title, description, sector, stack, track (ai, migration or other) and client only when the client register approves naming them; its body opens with ## Challenge, ## Strategy, ## Solution and ## Results, each with a bold one-line statement first. See the editorial_rules resource."New value: +"What the draft is: \"post\" (the default, a blog post) or \"case-study\" (content/case-studies, at /case-studies/<slug>). A case study's frontmatter is title, description, sector, stack, track (ai, migration or other) and client when the client register approves naming them or the engineer says the client agreed (client_confirmed); its body opens with ## Challenge, ## Strategy, ## Solution and ## Results, each with a bold one-line statement first. See the editorial_rules resource."
  8. Changed2 schema fields changed
    • addedInput schema / properties / kind
      Added value: +{
      +  "default": "post",
      +  "description": "What the draft is: \"post\" (the default, a blog post) or \"case-study\" (content/case-studies, at /case-studies/<slug>). A case study's frontmatter is title, description, sector, stack, track (ai, migration or other) and client only when the client register approves naming them; its body opens with ## Challenge, ## Strategy, ## Solution and ## Results, each with a bold one-line statement first. See the editorial_rules resource.",
      +  "enum": [
      +    "post",
      +    "case-study"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / sources
      Added value: +{
      +  "description": "A case study only: the engineer's own notes and the project's records (README, changelog, metrics they gave you) its numbers come from, as text, at most 100,000 characters. Every number in the case study is checked against these; one that isn't here is a finding. A source is not an approval: a client's metric also needs the client register's approval. Ask the engineer for outcome numbers; never invent them.",
      +  "type": "string"
      +}
  9. Changed1 schema field changed
    • addedInput schema / properties / brief_id
      Added value: +{
      +  "description": "The brief_id get_brief returned, when the post is from today's brief: it marks the brief done",
      +  "type": "string"
      +}
  10. First observed

TDQS

A4.5/5.0
Behavior4/5

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

Adds substantial context beyond the annotations: the required Microsoft sign-in with scope blog.write, the side effect that the site builds a preview and emails it to the engineer, the return values (id and text_hash), and the explicit guarantee that it never publishes. Idempotency is already declared by annotations, and the description doesn't restate it, which is correct. The remaining gap is minor: it doesn't say what happens on lint failures or validation rejection.

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

Conciseness4/5

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

The critical constraints are front-loaded: auth, then what gets filed, then what to send, then the next step, then 'Never publishes'. It is dense but nearly every clause carries a rule; the staccato fragments ('Lint it clean first.') and the long middle sentence on markdown slightly hurt readability.

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

Completeness4/5

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

For an 11-parameter mutation tool with an output schema and annotations, the description covers auth, side effects, return values, sequencing and the no-publish guarantee. Images and client_confirmed are not mentioned, but the schema documents both in detail, so the omission is not blocking.

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 coverage is already 91%, so the baseline is 3; the description earns above that by tying parameters to workflow conditions ('brief_id when it comes from get_brief', 'from_idea when it continues an idea they emailed') and by stating the frontmatter minimum ('title and description at least') and that sources must be the engineer's own quoted words. It leaves images, post_type and client_confirmed to the schema, which is reasonable at this coverage.

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?

States a specific verb and resource ('File a post ... under the engineer's byline, exactly as written') and immediately scopes the variant ('with kind "case-study", a case study'). It also distinguishes itself from publish_draft ('Never publishes') and points forward to check_draft, so an agent can place it in the workflow without opening the schema.

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?

Gives explicit preconditions and sequencing: 'Lint it clean first', use brief_id 'when it comes from get_brief', from_idea 'when it continues an idea they emailed', and 'next, check_draft with the id'. It also rules out the publishing alternative outright, leaving little to infer about when to call this versus its siblings.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.