Company Profile logo

Company Profile

OrganizationPopular
ginlix-ai
company-profile

One-page company profile slide, four quadrants of overview, financial summary, share price chart and key facts. Also the compact profile paragraph when it has to sit inside a memo, a deck or a chat reply. Triggers on one-page profile, tear sheet, company snapshot, profile slide, quick profile of [company].

Overview

Publisherginlix-ai
RepositoryLangAlpha
Skill namecompany-profile
Stars
1.8K
Forks
288
Bundled files
Instructions only
LicenseApache-2.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by ginlix-ai on GitHub. Read the source before you install it.

Installation

Install the Company Profile AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/ginlix-ai/LangAlpha.git /tmp/LangAlpha
mkdir -p .claude/skills
cp -r /tmp/LangAlpha/plugins/langalpha_research/skills/company-profile .claude/skills/company-profile
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Company Profile in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Company Profile on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Company Profile is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Company Profile

A single slide that answers "what is this company" for a reader with thirty seconds. Four quadrants, all four full: overview, financial summary, share price or valuation chart, key facts. This is the front page of a pitch book and the first page of a diligence pack, and it is the one slide in a deck allowed to be a document, because nobody presents from it, they read it off the page.

Build it with the pptx skill. Its geometry, palette, build-script discipline and verification scripts all apply unchanged, and this file only describes what goes inside that frame. Reach for html-report instead when the answer wants two pages of prose, and comps-analysis when the question is how the company prices against its peers rather than what it is.

Evidence labels, source tiers, staleness, the readiness posture and the intake limits: .agents/skills/research-conventions/SKILL.md, read before the first deliverable.

Scope

The profile is a baseline: what is true about this company, sourced, on one page. It is not a recommendation, and it holds no view. The moment the work turns into a thesis, a scenario set, a valuation argument or a call on the stock, it has stopped being a profile: finish the baseline, then hand off and say so. .agents/skills/initiating-coverage/SKILL.md owns the thesis, .agents/skills/comps-analysis/SKILL.md owns relative valuation, .agents/skills/earnings-preview/SKILL.md owns the setup into a print. Expanding the slide to carry a view is the failure this rule exists to catch, because a one-pager that argues reads as fact to everyone downstream of it.

Workflow

1. Scope it before researching

Confirm the entity first, then ask what the slide is for.

Entity identity. Establish, before any pull: the exact issuer (a similarly named parent, subsidiary or unrelated company is the classic wrong answer), the listing line (ticker and exchange, and which share class where more than one trades), and the fiscal year end. Everything downstream carries this, and a profile of the wrong listing line is wrong in every quadrant at once.

Then run intake per .agents/skills/research-conventions/references/intake.md: read the mandate memory, ask only about the forks it leaves open, recommended option first, and start on the recommendation when no answer comes back, disclosing it as a default. Two forks are worth a question here:

  • Format. One slide, recommended, or a profile deck: this slide plus two or three elaboration slides.
  • Baseline, which decides what survives the character budget below: long-only (durability, capital allocation), hedge-fund (positioning, float, borrow, days to exit), coverage starter (what a new analyst needs first), index constituent (weight, passive ownership, flow), diligence (counterparty, contracts, liquidity). Offer the two the mandate makes plausible rather than the whole menu, and recommend the one it implies.

Whether the company is public or private is settled from the pull rather than asked: a private company has no share price, so quadrant 4 becomes holders, funding history and recent developments.

Asking after the research is doing the research twice.

2. Pull the data

NeedSource
Profile, sector, market cap, consensus estimates, price targets, earnings historyget_company_overview
Revenue, EBITDA, margins, EPS, FCF across three yearsget_financial_statements and get_growth_metrics from the fundamentals MCP server
Forward-year revenue and EPSyf_analysis MCP get_revenue_estimates and get_earnings_estimates, the +1y record's avg, labelled E with numberofanalysts; forward EBITDA, margins and FCF have no consensus feed, so those cells carry an evidence gap rather than a derived figure
EVget_historical_valuation (enterpriseValue, alongside the DCF fair value)
EV/EBITDA, P/Eget_financial_ratios (evToEBITDA from key_metrics, priceToEarningsRatio from ratios)
EV/Revenuecomputed from enterpriseValue and the revenue line, since no tool returns the ratio
Share count and floatget_shares_float (outstandingShares, floatShares, freeFloat)
Insider buying and sellingget_insider_trades (transactions plus the buy/sell statistics)
Institutional holdingsyf_analysis MCP get_institutional_holders (holder, shares, value, pctheld), labelled with the record's date_reported, which is the filing quarter and not today; empty data is a company with none reported rather than an evidence gap
Named officersget_key_executives
One year of daily closes for the price chartget_stock_data from the price-data MCP server (interval="1day"), called inside execute_code so the rows land in Python where the chart step can save them
Business description, segment and geographic mixget_sec_filing (10-K, Item 1 Business and MD&A)
Recent news, private-company facts, brand colourWebSearch and WebFetch

Normalise before writing anything down: one currency, one scale ($mm or $bn, never mixed on one slide), one fiscal-year convention, and every figure labelled A for actual or E for estimate. Mark unaudited, preliminary, pro-forma, adjusted and company-defined figures as such in the bullet itself, since a pro-forma revenue figure sitting unlabelled beside a reported one is two different metrics in one column.

Provenance travels with every metric, even though the slide shows only the number. Keep period, units, source and confidence beside each figure while researching: the slide prints the number, the source line prints the tools and documents behind it, and the outline you show the user carries all four so a wrong figure is traceable in seconds rather than re-pulled.

Flag a conflict rather than picking silently. Two sources disagreeing on revenue, EBITDA, debt, share count or market cap; a data tool differing from the filing; the company's deck differing from its filing; a newer filing superseding the figure already written down. Resolve down the tier list and record the selection per .agents/skills/research-conventions/references/evidence.md, and where the conflict is material to the slide, say which figure was used in the source line.

3. Outline before code

Write the four quadrants out as plain text with the real numbers already in place. No placeholders: a bullet you cannot fill is a bullet the slide does not get. Show the outline and the accent colour, then build.

4. Build, render, look, shrink

Follow the pptx loop exactly:

  1. Write work/<task>/build_<name>.js and run it with NODE_PATH=$(npm root -g) node work/<task>/build_<name>.js.
  2. python .agents/skills/pptx/scripts/check.py work/<task>/<name>.pptx --strict, which reads the written file and reports anything off the slide, overlapping or overflowing.
  3. python .agents/skills/pptx/scripts/render.py work/<task>/<name>.pptx --montage, then open the PNG and read it. Look for a bullet wrapping into the quadrant below it, a table row crossing the footer, an axis label clipped at the bottom, and a title sitting on top of the first quadrant header.
  4. When anything overflows, fix it in this order: drop the body font by 1 to 2pt (12 to 11, then 11 to 10, which is the floor), then shorten the bullet, then move the boundary between the two rows. Re-render and look again.

Steps 3 and 4 are not optional and neither is the looking. check.py estimates overflow from font size and character count, so a pass is a reason to look, not a substitute for looking. A profile slide is the densest thing this repo produces, and density is exactly where the estimate and the renderer disagree.

Layout

16:9, LAYOUT_WIDE, 13.333 x 7.5 in, with the 0.6 in side margins and the title band from the pptx skill left alone. The content band, y 1.75 to 6.60, splits into four equal quadrants:

x=0.600                          x=6.833                       x=12.733
+--------------------------------+------------------------------+  y=1.75
| 1  Company Overview            | 2  Business and Positioning  |
| w=5.90  h=2.30                 | w=5.90  h=2.30               |
+--------------------------------+------------------------------+  y=4.05
| 3  Financial Summary           | 4  Share Price / Key Facts   |
| w=5.90  h=2.35                 | w=5.90  h=2.35               |
+--------------------------------+------------------------------+  y=6.60
ElementxywhType
Title, Company Name (TICKER)0.600.4512.130.6028pt bold
Kicker: units, periods, as-of date0.601.0512.130.3514pt
Rule0.601.4212.130.02
Quadrant header, top rowcol x1.755.900.4016pt bold
Quadrant hairline, top rowcol x2.175.900.01
Quadrant body, top rowcol x2.235.901.8212pt
Quadrant header, bottom rowcol x4.255.900.4016pt bold
Quadrant hairline, bottom rowcol x4.675.900.01
Quadrant body, bottom rowcol x4.735.901.8712pt
Source line0.606.9512.130.3010pt

Column x is 0.600 for quadrants 1 and 3, 6.833 for quadrants 2 and 4. The 0.333 in gutter is the only thing between the columns: white background, no fills, no shading, no boxes drawn around the quadrants.

Header boxes are 0.40 in and not a hair less. check.py measures a box against its text after taking off the 0.05 in inset top and bottom, so a 16pt line needs 19.2pt of clear height, and a 0.32 in box fails the overflow check even though the render looks fine.

12pt body is a deliberate exception to the deck-wide 16 to 18pt in pptx, and it is the only slide that gets it. check.py holds the hard floors either way: 10pt for body text, 14pt for table text.

Density budget

A quadrant that looks sparse has not been researched. Fill all four, then measure each against the column width.

QuadrantContentTarget
1 Company OverviewHQ, founded, employees, CEO and CFO, exchange and ticker, market cap, industry, one defining statistic6 to 8 bullets
2 Business and Positioningrevenue drivers, product or segment mix with percentages, market share, the moat in one clause, customer count or concentration, geographic mix6 to 8 bullets
3 Financial SummaryRevenue, growth, EBITDA, EBITDA margin, EPS, FCF, EV/EBITDA over three columns (FY-1A, FY0A, FY+1E)a table of header plus 6 rows, or a chart, never both
4 Share Price or Key Factsone year of daily closes; for a private company, top holders with percentages, funding history, recent developmentsa chart, or 5 to 7 bullets

At 12pt across a 5.90 in column, check.py fits roughly 70 characters on a line (width_in * 72 / (pt * 0.5)), so a bullet over 70 characters takes two lines and costs the quadrant a fact. Counting paragraph spacing, each body box holds 7 to 8 one-line bullets. Write to that budget: pack facts, never pad them.

  • Combine related facts: HQ Austin, TX; founded 2003; 14,200 employees is one bullet, not three.
  • Always carry the number: $4.0bn revenue beats large revenue, and +28% y/y beats growing fast.
  • Add the comparison that makes the number mean something: EBITDA margin 25.4% (peer median 18%).
  • Bold the lead term as its own run, { text: "Market position: ", options: { bold: true } }, so the quadrant scans as a list of labels.
  • Set bullet: { indent: 12 }. The pptxgenjs default leaves about a third of an inch of white between the glyph and the text, which is four characters of a 70-character line spent on nothing.

Never silently omitted. These are either on the slide with their as-of, or named in the evidence gaps: market cap, float, average daily volume and days to exit, index membership, passive and ETF ownership, top holders, short interest, borrow, analyst coverage count, and the consensus setup. A missing one of these changes what a reader can do with the page, so its absence is information.

Pair the fact with the decision wherever the decision is not obvious from the number: float speaks to capacity and squeeze risk, days to exit answers whether a position can be built or unwound at all, borrow prices the other side of the trade. Float 62%; 14 days to exit at 20% ADV is one bullet doing two jobs, which is how a data table becomes a decision aid inside a 70-character line.

Evidence gaps. One compact block, never a table of empty fields. Where there are one or two gaps, they ride at the end of the source line: Not sourced: short interest, borrow (as of unavailable). Where there are more, they take the last bullet of quadrant 4 as a single line starting Not sourced:. Each gap names what is missing and, where it is not obvious, what would supply it. A gap that costs the reader a decision is worth a bullet more than the least surprising fact on the slide.

If a quadrant still runs short, the facts usually missing are segment percentages, customer concentration, guidance against consensus, and insider ownership. If it runs long, cut the least surprising fact before you cut the font.

Content rules

Every adjective carries its number. Best-in-class margins becomes EBITDA margin 25.4% (peer median 18%); dominant becomes 41% share, next largest 17%; high quality becomes the metric that makes it so. Where the number does not exist, the claim does not go on the slide.

Title the valuation block by what the evidence supports. With only historical financials and derived LTM multiples behind it, the heading is Valuation Context or LTM Multiples, and it stays that way until forward estimates, peer evidence, target-price evidence or an explicit statement of market expectations is actually sourced. A heading promising a forward debate the sourcing cannot carry is the one place a factual page can mislead without printing a single wrong number.

Contain a live event. A pending transaction, a rumour, an activist position or a regulatory action that is material but is not what the user asked about goes in exactly three places: one line in the read, the catalyst or risk bullet, and the evidence gap for whatever primary document is still missing. It does not get threaded through the business description, the financial summary and the valuation block as well, which is how one unresolved event takes over a page that was asked to describe a company.

Reader-facing labels. The slide prints the reader's word for each evidence label, one per label, per Reader-facing labels in .agents/skills/research-conventions/references/evidence.md, where a model-derived figure prints as derived in the space a slide has.

Build script

The chart series comes from Python, not from the direct tool. get_daily_prices answers in Markdown, and past fourteen trading days that answer is a summary rather than the rows, so a year of closes never reaches the build script through it. Pull the series with get_stock_data on the price-data MCP server instead: it returns {symbol, interval, currency, timezone, count, data, source}, where data is a list of {date, open, high, low, close, volume} bars, oldest first. The research step keeps the two fields the chart reads and writes them to work/<ticker>/prices.json; the axis range then comes from the data, never from a typed bound.

python
import json
from tools.price_data import get_stock_data

bars = get_stock_data("ACME", interval="1day",
                      start_date="2025-09-05", end_date="2026-09-05")["data"]
with open("work/acme/prices.json", "w") as f:
    json.dump([{"date": b["date"], "close": b["close"]} for b in bars], f)
js
const PptxGenJS = require("pptxgenjs");
const fs = require("fs");

const prices = JSON.parse(fs.readFileSync("work/acme/prices.json", "utf8"));
const months = prices.map((p) => p.date);
const closes = prices.map((p) => p.close);
const lo = Math.floor(Math.min(...closes) * 0.9), hi = Math.ceil(Math.max(...closes) * 1.1);

const INK = "1A1A1A", MUTED = "5A5A5A", RULE = "D8D5D0", ACCENT = "1F4E79";
const FONT = "Arial", M = 0.6, W = 13.333, CONTENT_W = W - 2 * M;
const COL_W = 5.9, COL_X = [M, 6.833];
const ROW = [{ head: 1.75, rule: 2.17, body: 2.23, h: 1.82 },
             { head: 4.25, rule: 4.67, body: 4.73, h: 1.87 }];

const pptx = new PptxGenJS();
pptx.layout = "LAYOUT_WIDE";
const slide = pptx.addSlide();
slide.background = { color: "FFFFFF" };

slide.addText("Acme Corporation (ACME)", { x: M, y: 0.45, w: CONTENT_W, h: 0.6,
  fontFace: FONT, fontSize: 28, bold: true, color: INK, valign: "middle" });
slide.addText("$ in millions unless noted; FY2026E is consensus; prices as of 2026-09-05",
  { x: M, y: 1.05, w: CONTENT_W, h: 0.35, fontFace: FONT, fontSize: 14, color: MUTED, valign: "top" });
slide.addShape("rect", { x: M, y: 1.42, w: CONTENT_W, h: 0.02, fill: { color: RULE } });

// One helper for all four quadrants, so no header can drift from its neighbour.
function quadrant(col, row, heading) {
  const x = COL_X[col], r = ROW[row];
  slide.addText(heading, { x, y: r.head, w: COL_W, h: 0.40,
    fontFace: FONT, fontSize: 16, bold: true, color: ACCENT, valign: "middle" });
  slide.addShape("rect", { x, y: r.rule, w: COL_W, h: 0.01, fill: { color: RULE } });
  return { x, y: r.body, w: COL_W, h: r.h };
}

const bullets = (lines) => lines.map((t) => ({ text: t, options: { bullet: { indent: 12 } } }));

const q1 = quadrant(0, 0, "Company Overview");
slide.addText(bullets([
  "HQ Austin, TX; founded 2003; 14,200 employees",
  "CEO J. Rivera (2019); CFO M. Osei (2022)",
  "NASDAQ: ACME; market cap $18.4bn; float 92%",
]), { ...q1, fontFace: FONT, fontSize: 12, color: INK, valign: "top", paraSpaceAfter: 3 });

const q2 = quadrant(1, 0, "Business and Positioning");
slide.addText(bullets([
  "Industrial sensors and controls; 61% of revenue is recurring service",
  "Second by share in North American process automation",
  "Installed base of 40k sites; switching cost is recertification",
]), { ...q2, fontFace: FONT, fontSize: 12, color: INK, valign: "top", paraSpaceAfter: 3 });

const q3 = quadrant(0, 1, "Financial Summary");
const head = { fill: { color: ACCENT }, color: "FFFFFF", bold: true };
slide.addTable(
  [[{ text: "$mm", options: head }, { text: "FY2024A", options: head },
    { text: "FY2025A", options: head }, { text: "FY2026E", options: head }],
   ["Revenue", "3,410", "4,020", "4,610"],
   ["EBITDA", "742", "928", "1,105"]],
  { ...q3, colW: [2.0, 1.3, 1.3, 1.3], fontFace: FONT, fontSize: 14, color: INK,
    rowH: 0.26, valign: "middle", border: { type: "solid", pt: 1, color: RULE } }
);

const q4 = quadrant(1, 1, "Share Price, Last 12 Months");
slide.addChart(pptx.ChartType.line, [{ name: "ACME", labels: months, values: closes }],
  { ...q4, chartColors: [ACCENT], showLegend: false, lineSmooth: false, lineDataSymbol: "none",
    valAxisMinVal: lo, valAxisMaxVal: hi,   // never zero-based; see below
    catAxisLabelFontFace: FONT, catAxisLabelFontSize: 12, catAxisLabelColor: MUTED,
    valAxisLabelFontFace: FONT, valAxisLabelFontSize: 12, valAxisLabelColor: MUTED,
    valGridLine: { color: RULE, style: "solid", size: 1 }, catGridLine: { style: "none" } }
);

slide.addText("Source: company filings, fundamentals MCP server, get_stock_data. Prices as of 2026-09-05.",
  { x: M, y: 6.95, w: CONTENT_W, h: 0.3, fontFace: FONT, fontSize: 10, color: MUTED });

pptx.writeFile({ fileName: "work/acme/acme_profile.pptx" })
  .then(() => console.log("written"));

A table is as tall as rowH times its row count whatever h says, so header plus 6 rows at 0.26 is 1.82 in inside the 1.87 in body box. A seventh row pushes it past the content band toward the footer, which check.py reports as out of bounds.

Chart or table, never both

Quadrant 3 is a table by default: it carries nine numbers in the space a chart spends on one series. Swap in a chart only when the shape of the trend is the point, and then drop the table rather than shrinking both.

DataChart
One year of daily closesline, unsmoothed, no markers
Revenue or EBITDA over five periodscolumn
Segment or geographic mixhorizontal bar, sorted
Product mix, four slices or fewerpie with percentages shown

Charts are native addChart parts, one colour per series, axis labels at 12pt. Units go in the kicker or the axis title, not on every data label.

A price line is never zero-based. pptxgenjs starts the value axis at 0 by default, which pins a year of trading into the top fifth of the box and draws every stock as a flat line. Set valAxisMinVal and valAxisMaxVal around the series, roughly 10 percent outside the low and the high. This is the defect the render catches and check.py never will: the geometry is perfect and the chart says nothing.

Colour

The house palette in pptx is the default and it is enough: ink, grey, paper, one accent. When the user asks for the company's brand colour, search for the actual hex rather than guessing, use it as the single accent (quadrant headers, table header fill, the price line) and leave the rest in the house greys. One accent, one meaning, and green and red still mean gain and loss and nothing else.

Private companies

Quadrant 4 has no share price, so it becomes holders and history: top five holders with percentages, funding rounds with dates and amounts, and the two or three developments from the last ninety days a reader would ask about. The sources shift to the corporate site, press releases and news search, so the source line names them and the kicker says which figures are estimates.

Compact profile

When the profile has to sit inside a memo, a deck or a chat message rather than on its own page, compress it to one paragraph in a fixed order: what the company does and how it makes money, scale (revenue, growth, margin) with the period, the balance-sheet and positioning facts that bear on the reader's decision, the valuation context with its as-of, and the one thing that would change the picture. Two hundred words or fewer, every number carrying its period and source, and the same never-silently-omit list applies: what is not sourced is named in the last sentence.

Profile decks

When the user asked for two or three more slides, the profile slide does not change. The rest are ordinary pptx content slides at 16 to 18pt body, one claim each, in the order business and market, financial detail, then leadership or ownership. Every one elaborates something the profile slide already claimed, so a reader who stops after the first page has still been told the truth.

Checklist

  • Scope settled before research started, from the mandate memory or from intake, with any default taken named in the delivery message.
  • All four quadrants at their target density, none visibly lighter than its neighbour.
  • Every bullet under 70 characters and on one line in the render.
  • Quadrant 3 is a table or a chart, not both.
  • One currency and one scale throughout, every figure labelled A or E.
  • check.py --strict passes.
  • The montage was rendered and looked at, not just generated.
  • Nothing under 10pt, table text at 14pt, at most two font families.
  • Source line names the tools behind the numbers and the as-of date.
  • The build script sits next to the deck and reruns cleanly.

Content, before the render is looked at:

  • Entity confirmed: issuer, ticker, exchange, share class, fiscal year end.
  • Every metric traceable to period, units, source and confidence.
  • Every adjective carries its number, or is gone.
  • Valuation heading matches the evidence actually sourced.
  • Conflicts flagged with the selected figure, and preliminary or pro-forma figures labelled.
  • Nothing from the never-silently-omit list is missing without appearing in the evidence gaps.
  • Evidence gaps present, in the source line or as one bullet, never as a table of blanks.
  • One posture, stated once near the top, read from the ladder in .agents/skills/research-conventions/SKILL.md.
  • No thesis, no recommendation, no scenario: the page states what is, and the handoff names who owns the rest.
  • The delivery message names the next analytical step this profile enables.

Frequently asked questions

What does the Company Profile AI skill do?

One-page company profile slide, four quadrants of overview, financial summary, share price chart and key facts. Also the compact profile paragraph when it has to sit inside a memo, a deck or a chat reply. Triggers on one-page profile, tear sheet, company snapshot, profile slide, quick profile of [company].

Why use Company Profile on TypingMind?

Because you install it once and use it with any model. Company Profile is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Company Profile in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/ginlix-ai/LangAlpha/tree/main/plugins/langalpha_research/skills/company-profile. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Company Profile?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Company Profile?

As many as you like. As long as a model supports skills, you can use Company Profile with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Company Profile AI skill free?

Yes. It is published on GitHub by ginlix-ai under the Apache-2.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇