# Microsoft Project (nuget · HorizunMsProjectMcp)

Audit, reschedule and author Microsoft Project schedules. No Java, no Project install.

- Trust score: 78/100 (medium)
- Change this week: 0
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-09-20

## Components

- nuget · `HorizunMsProjectMcp`: 78/100 (this document), [markdown](https://verifymcp.io/servers/horizungroup-horizun-msproject-mcp/horizunmsprojectmcp.md), [page](https://verifymcp.io/servers/horizungroup-horizun-msproject-mcp/horizunmsprojectmcp)

## Channel facts

- Registry: `nuget`
- Package: `HorizunMsProjectMcp`
- Version: `1.0.2`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-09-20.

- **Supply Chain Security**: 88/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - Install-script risk not yet assessed.
  - No production dependencies, so there is no dependency health to assess.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 46 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 68/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 5013 tokens (~200/item across 25 items; 25 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 87/100
  - Stability observed for 26 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 25 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 25 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the Microsoft Project MCP server?

Microsoft Project runs locally as a NuGet package, launched with dnx HorizunMsProjectMcp@1.0.2 --yes. Ready-made configuration for Claude, Cursor, VS Code, Codex and 3 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add horizungroup-horizun-msproject-mcp -- dnx HorizunMsProjectMcp@1.0.2 --yes
```

### Cursor

```json
{
  "mcpServers": {
    "horizungroup-horizun-msproject-mcp": {
      "command": "dnx",
      "args": [
        "HorizunMsProjectMcp@1.0.2",
        "--yes"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "horizungroup-horizun-msproject-mcp": {
      "command": "dnx",
      "args": [
        "HorizunMsProjectMcp@1.0.2",
        "--yes"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add horizungroup-horizun-msproject-mcp -- dnx HorizunMsProjectMcp@1.0.2 --yes
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "horizungroup-horizun-msproject-mcp": {
      "type": "local",
      "command": [
        "dnx",
        "HorizunMsProjectMcp@1.0.2",
        "--yes"
      ],
      "enabled": true
    }
  }
}
```

### Hermes

```yaml
mcp_servers:
  horizungroup-horizun-msproject-mcp:
    command: "dnx"
    args: ["HorizunMsProjectMcp@1.0.2", "--yes"]
```

### Netclaw

```json
{
  "McpServers": {
    "horizungroup-horizun-msproject-mcp": {
      "Transport": "stdio",
      "Command": "dnx",
      "Arguments": [
        "HorizunMsProjectMcp@1.0.2",
        "--yes"
      ]
    }
  }
}
```

### Other

```json
{
  "mcpServers": {
    "horizungroup-horizun-msproject-mcp": {
      "command": "dnx",
      "args": [
        "HorizunMsProjectMcp@1.0.2",
        "--yes"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-09-20 (score 78, +1)

No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-18 (score 77, −3)

- [functional] Stability: pass → 0.80

### 2026-09-17 (score 80, +1)

- [security] Stability: 0.97 → pass

### 2026-09-15 (score 79, +1)

No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-13 (score 78, +1)

No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-09-11 (score 77, −3)

- [functional] Stability: pass → 0.80

### 2026-09-10 (score 80, +1)

- [security] Stability: 0.97 → pass

### 2026-09-08 (score 79, +1)

No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.

## MCP tools (25)

### `project_health` (~135 tokens)

Diagnose what this server can do on this machine. Call it first in every session. Reports the active backend, runtime, whether Microsoft Project is installed AND whether its COM server actually starts, and a capability matrix the other tools honour. When something is wrong it returns the exact diagnosis and a repair path, not a stack trace. Pass deep=true to genuinely launch Microsoft Project instead of only reading its registration — slower and visible on screen, but the only way to know COM works.

Input parameters:

- `deep` (boolean): Launch the Microsoft Project COM server for real instead of only inspecting its registration. Starts Project and closes it again. Defaults to false.

### `bim_link` (~219 tokens)

Tie schedule tasks to the model elements they build, matching on a shared code (HRZ_COD_PRES, a keynote, a budget code). op='suggest' proposes the mapping from an element export and separates out anything that matched only on a code prefix for you to confirm; 'set' stores it; 'get' reads it back; 'clear' removes it. The mapping lives in a sidecar next to the schedule, so re-exporting the model never touches the planner's file.

Input parameters:

- `codeField` (string): Task custom field holding the code, e.g. 'Text1'. Defaults to Text1.
- `elementsPath` (string|null): Path to the element export (JSON array or CSV with elementId, code, quantity, unit). Required for suggest.
- `handle` (string, required): Document handle from project_open.
- `op` (string): suggest, set, get, or clear.
- `reviewBelow` (number): Mappings below this confidence are listed for review instead of stored. Defaults to 100.

### `schedule_qa` (~204 tokens)

Run the DCMA 14-point schedule assessment plus Horizun's own rules, and report what is wrong with the schedule. This is the industry standard for judging whether a schedule can be run on: missing logic, leads and lags, hard constraints, high float and duration, negative float, invalid dates, unresourced work, missed baseline tasks, CPLI and BEI. Checks that genuinely cannot be evaluated (no baseline stored, no scheduling engine) are reported as not evaluated with the reason — never as a pass.

Input parameters:

- `budgetCodeField` (string|null): Custom field carrying the budget code, e.g. 'Text1'. Supply it to also check that every task is tied to the cost model — the same code the BIM tools match on.
- `handle` (string, required): Document handle from project_open.
- `statusDate` (string|null): Status date for the progress checks, yyyy-MM-dd. Defaults to the project's own status date, then today.

### `calendars_write` (~98 tokens)

Manage working calendars: create and delete them, and add non-working exceptions for holidays, site shutdowns or a rainy season. The weekly working-hours pattern itself is not editable here. Verified and dry-runnable exactly as tasks_write describes.

Input parameters:

- `dryRun` (boolean): Simulate against a copy and report the impact without committing.
- `handle` (string, required): Document handle from project_open.
- `ops` (array, required): The calendar operations to apply.

### `schedule_update` (~241 tokens)

Engine-level operations that take no per-task payload: save or clear a baseline, set the status date, reschedule incomplete work, level resources, or force a recalculation. Levelling and rescheduling are the two that do the most damage by accident, so they require a dry run to be seen first. Operations that need Microsoft Project's scheduling engine are refused outright on the MPXJ backend rather than approximated.

Input parameters:

- `baseline` (integer): Baseline slot 0-10 for save_baseline and clear_baseline. Defaults to 0.
- `dryRun` (boolean): Simulate against a copy and report the impact without committing.
- `handle` (string, required): Document handle from project_open.
- `op` (string, required): save_baseline, clear_baseline, set_status_date, reschedule_incomplete, level_resources, or recalculate.
- `overwriteBaseline` (boolean): Allow save_baseline to replace a baseline that already holds data. Off by default: overwriting one destroys the original plan every variance is measured against.
- `statusDate` (string|null): Status date for set_status_date and reschedule_incomplete, yyyy-MM-dd.

### `project_import` (~124 tokens)

Bring updates in from a CSV or JSON file — typically progress collected in the field. Runs plan-first: by default it matches rows to tasks by uid and returns the field-by-field diff without changing anything. Pass apply=true once you have read the plan, and the changes go through tasks_write so every one of them is verified by re-reading the model.

Input parameters:

- `apply` (boolean): Apply the plan. Defaults to false — plan only.
- `handle` (string, required): Document handle from project_open.
- `path` (string, required): Path to the CSV or JSON file to import.

### `project_export` (~166 tokens)

Export the schedule for another tool. 'mspdi' and 'mpx' write real schedule files; 'csv' and 'json' write a flat task table; 'pbip_dataset' writes the shaped dataset our Power BI report consumes — tasks, assignments, earned value and the S-curve — rather than a raw dump.

Input parameters:

- `format` (string): csv, json or pbip_dataset for a flat table; mspdi, mpx, mpp, xer, pmxml, planner or sdef for a real schedule file.
- `handle` (string, required): Document handle from project_open.
- `path` (string, required): Output file path.
- `statusDate` (string|null): Status date used for the earned-value block in pbip_dataset, yyyy-MM-dd.

### `baseline_compare` (~182 tokens)

Earned-value analysis against a stored baseline: BCWS, BCWP, ACWP, schedule and cost variance, SPI, CPI, EAC and TCPI, for the whole project and optionally per top-level WBS branch, plus the tasks with the worst slippage. This is the number a project board asks for and what feeds the S-curve. Says so plainly when no baseline is stored rather than returning zeros that look real.

Input parameters:

- `baseline` (integer): Which baseline to measure against: 0 (the main one, default) through 10.
- `byBranch` (boolean): Also break the metrics down by top-level WBS branch. Defaults to true.
- `handle` (string, required): Document handle from project_open.
- `statusDate` (string|null): Status date, yyyy-MM-dd. Defaults to the project's own status date, then today.

### `tasks_query` (~481 tokens)

The workhorse read. Filter, sort, and page through tasks without pulling the whole schedule into context. Every task is identified by its stable uid — the id field is the row number and shifts when tasks are inserted, so never use it to address a task in a write. Defaults to a compact field set and 50 rows; ask for more only when you need it.

Input parameters:

- `critical` (boolean|null): true = only critical tasks, false = only non-critical, null = both.
- `cursor` (integer): Row offset from a previous nextCursor.
- `customField` (string|null): Custom field filter, e.g. 'Text1'. Pair with customValue.
- `customValue` (string|null): Value the custom field must contain.
- `dateField` (string|null): Date filter field: start, finish, baseline_finish, or deadline.
- `dateFrom` (string|null): Date filter lower bound, yyyy-MM-dd.
- `dateTo` (string|null): Date filter upper bound, yyyy-MM-dd.
- `handle` (string, required): Document handle from project_open.
- `includeCustom` (boolean): Include the Text1..Text30 custom fields on each row. Off by default — they are bulky.
- `limit` (integer): Maximum rows to return. Defaults to 50.
- `maxFloatDays` (number|null): Only tasks whose float is at or below this many days — use 0 to find the driving work.
- `milestone` (boolean|null): true = only milestones, false = exclude milestones, null = both.
- `minDurationDays` (number|null): Only tasks whose duration exceeds this many days.
- `resource` (string|null): Only tasks this resource is assigned to (name substring).
- `shape` (string): Shape: flat (default), leaf_only, or summary_only.
- `sort` (string): Sort by start (default), finish, float, duration, or wbs.
- `status` (string|null): Status filter: not_started, in_progress, complete, or late.
- `text` (string|null): Case-insensitive substring match on name and notes.
- `uids` (array|null): Restrict to these task uids.
- `wbsPrefix` (string|null): Only tasks whose WBS starts with this prefix, e.g. '1.2'.

### `project_open` (~220 tokens)

Open a schedule — or start a new one — and get a handle for every other tool. Reads .mpp, .mpt, .mpx, MSPDI .xml, Primavera .xer and .pmxml, Asta .pp and more, with no Microsoft Project needed. Returns a fingerprint of the file; later writes revalidate it and refuse if the file changed on disk in the meantime, so a stale handle can never overwrite somebody else's edits. Pass create=true to begin an empty schedule at that path instead of reading one.

Input parameters:

- `create` (boolean): Start a new empty schedule instead of reading an existing file. Refuses to clobber an existing file.
- `mode` (string): 'readwrite' (default) or 'readonly'. A read-only handle refuses every write tool.
- `name` (string|null): Project name for a newly created schedule.
- `path` (string, required): Absolute path to the schedule file.
- `startDate` (string|null): Project start date for a newly created schedule, yyyy-MM-dd.

### `links_write` (~93 tokens)

Add, remove, and change dependencies in one batch. Cycles are detected and refused before anything is applied, with the offending chain named in the rejection. Verified and dry-runnable exactly as tasks_write describes.

Input parameters:

- `dryRun` (boolean): Simulate against a copy and report the impact without committing.
- `handle` (string, required): Document handle from project_open.
- `ops` (array, required): The dependency operations to apply.

### `tasks_write` (~174 tokens)

Create, update, delete and re-outline tasks in one batch. Progress (percentComplete, actual dates) is an ordinary update. Tasks are addressed by their stable uid — never by row id. Every change is re-read from the model after the write and only then counted as applied; anything the schedule refused comes back under 'rejected' with the reason and what the value actually became. Pass dryRun=true to run the whole batch against a throwaway copy and see the impact — how many tasks move, how far the finish date shifts, whether the critical path changes — without touching the open document.

Input parameters:

- `dryRun` (boolean): Simulate against a copy and report the impact without committing.
- `handle` (string, required): Document handle from project_open.
- `ops` (array, required): The operations to apply, in order.

### `schedule_generate` (~353 tokens)

Build a new schedule from an activity library produced by schedule_learn. Each activity gets the duration its history says it takes, and the dependencies that usually surround it are recreated between the activities you asked for. Returns an open handle, so run schedule_qa on it before trusting it and adjust with tasks_write — this is a first draft grounded in what actually happened on past projects, not a finished programme.

Input parameters:

- `activities` (array|null): Activity keys to include, as listed in the library. Omit to use every activity in it.
- `durationBasis` (string): 'median' (default) for a normal run, or 'p80' to plan with contingency.
- `libraryPath` (string, required): Path to the library JSON from schedule_learn.
- `name` (string|null): Name for the new project.
- `outputPath` (string, required): Path for the new schedule. Refuses to overwrite an existing file.
- `quantities` (object|null): Measured quantities per activity key, e.g. {"VACIADO LOSA": 340}. Where the library learned a productivity rate for that activity, the duration is sized from the quantity instead of copied from histo…
- `startDate` (string, required): Project start date, yyyy-MM-dd.
- `unitLabel` (string): Word naming a unit, used in the task names: 'apto', 'piso', 'torre'. Defaults to 'unidad'.
- `units` (integer): How many units to build — apartments, floors, blocks. Activities the library found to repeat unit by unit are created once per unit and chained, which is how construction schedules are actually shape…

### `schedule_target` (~142 tokens)

Test a schedule against a date you have been given. Reports whether the target is achievable, how many working days short it falls, the driving chain with the dates each task would have to hit, and every task the network does not actually hold in place — work with no predecessor or no successor, which never moves when its neighbours do and makes any target date arithmetic rather than a plan. Read-only.

Input parameters:

- `anchor` (string): 'finish' (default) to test a completion date, or 'start' to test a start date.
- `handle` (string, required): Document handle from project_open.
- `target` (string, required): The target date, yyyy-MM-dd.

### `resources_write` (~83 tokens)

Create, update, and delete resources, and assign or unassign them to tasks, in one batch. Verified and dry-runnable exactly as tasks_write describes.

Input parameters:

- `dryRun` (boolean): Simulate against a copy and report the impact without committing.
- `handle` (string, required): Document handle from project_open.
- `ops` (array, required): The resource operations to apply.

### `links_query` (~195 tokens)

Read the dependency network. Almost always you want the subgraph around a few tasks rather than every link, so pass uids and a depth. drivingOnly returns just the chain that actually pushes the finish date, which is what you want when asking why the project ends when it does.

Input parameters:

- `cursor` (integer): Row offset from a previous nextCursor.
- `depth` (integer): How many hops out from the seed tasks. 0 = immediate neighbours only. Defaults to 1.
- `direction` (string): 'pred', 'succ', or 'both' (default).
- `drivingOnly` (boolean): Return only the driving chain that sets the project finish date.
- `handle` (string, required): Document handle from project_open.
- `limit` (integer): Maximum rows. Defaults to 200.
- `uids` (array|null): Centre the subgraph on these task uids. Omit for the whole network.

### `bim_sync` (~219 tokens)

Move data across the schedule/model boundary, in either direction. direction='model_to_schedule' turns measured quantities into duration proposals at a stated productivity rate — proposals only, which you then apply with tasks_write. direction='schedule_to_model' writes one row per element carrying its task's dates and progress: that file drives 4D animation in Navisworks, element parameters in Revit, and the progress dashboard in Power BI.

Input parameters:

- `defaultProductivity` (number): Productivity to use when a unit is not listed. Defaults to 1.
- `direction` (string, required): model_to_schedule or schedule_to_model.
- `handle` (string, required): Document handle from project_open.
- `outputPath` (string|null): Output path for schedule_to_model (.csv or .json).
- `productivity` (object|null): Productivity per day per unit, e.g. {"m3": 25, "m2": 120}. Used by model_to_schedule.
- `statusDate` (string|null): Status date used to classify element progress, yyyy-MM-dd.

### `schedule_recovery` (~205 tokens)

Work out what is late, what it is costing the finish date, and which changes to the logic would actually recover time. Lists the late work ordered by how much of the schedule is stuck behind it, then measures recovery levers — removing lag on the driving chain, overlapping finish-to-start hand-offs, compressing the longest critical tasks. Every option is applied to a throwaway copy, rescheduled, and reported with the finish date it genuinely produces; an option that recovers nothing says so rather than being offered as advice. Nothing is written to the open document.

Input parameters:

- `handle` (string, required): Document handle from project_open.
- `maxOptions` (integer): How many recovery options to return. Defaults to 5.
- `statusDate` (string|null): Status date, yyyy-MM-dd. Defaults to the project's own, then today.
- `targetFinish` (string|null): The date you need to finish by, yyyy-MM-dd. Adds the gap to the report.

### `timephased_query` (~217 tokens)

Work or cost spread over time — the S-curve. Kept separate from the other reads because it is the expensive one: it refuses ranges that would generate an unreasonable number of buckets and tells you to coarsen the granularity instead of quietly returning tens of thousands of rows.

Input parameters:

- `from` (string|null): Range start, yyyy-MM-dd. Defaults to the project start.
- `granularity` (string): 'day', 'week' (default), or 'month'.
- `handle` (string, required): Document handle from project_open.
- `measure` (string): 'work' (default), 'cost', 'duration', 'baseline_work', or 'baseline_cost'. Use 'duration' on a schedule with no loaded hours or costs — many carry neither, and it is the only curve they can produce.
- `to` (string|null): Range end, yyyy-MM-dd. Defaults to the project finish.
- `uids` (array|null): Restrict to these task uids. Omit for the whole project.

### `resources_query` (~166 tokens)

Read resources, their assignments, and who is overbooked. Overallocation is computed day by day from the assignment spans — Microsoft Project's file format carries no such flag, so this is a real calculation rather than a field read.

Input parameters:

- `cursor` (integer): Row offset from a previous nextCursor.
- `handle` (string, required): Document handle from project_open.
- `includeAssignments` (boolean): Include each resource's assignments. Off by default — they are bulky.
- `limit` (integer): Maximum rows. Defaults to 50.
- `name` (string|null): Name substring filter.
- `overallocatedOnly` (boolean): Only resources that are overbooked on at least one day.
- `type` (string|null): Filter by type: work, material, or cost.

### `schedule_learn` (~262 tokens)

Mine finished schedules for how long each kind of activity actually takes and what usually comes before and after it. Reads any number of .mpp, MSPDI or Primavera files, normalises task names so the same activity matches across projects and units, and reports each activity's duration distribution — median, 80th percentile, range — together with its typical predecessors and successors and the lag between them. Save the result and hand it to schedule_generate to build a new schedule from experience rather than from a blank page.

Input parameters:

- `codeField` (string|null): Custom field holding the budget code, e.g. 'Text1', to carry into the library.
- `minOccurrences` (integer): Ignore activities seen fewer times than this. Defaults to 3.
- `paths` (array, required): Paths of past schedules to learn from.
- `quantitySources` (array|null): Element exports (the same CSV or JSON bim_link reads) carrying measured quantities per code. Supply them together with codeField and the library reports a productivity rate per activity — how much a…
- `savePath` (string|null): Where to save the library as JSON. Omit to return it without saving.

### `schedule_analyze` (~120 tokens)

Answer questions about the schedule without downloading it. Computes the critical path, the float distribution, the driving (longest) path, day-by-day resource overallocation, milestone status against deadlines and baseline, and the health of the dependency network. Ask for only the aspects you need — each one is computed independently.

Input parameters:

- `aspects` (array|null): Which analyses to run: critical_path, float_distribution, longest_path, overallocation, milestones, dependency_health. Omit for all except longest_path.
- `handle` (string, required): Document handle from project_open.

### `project_save` (~198 tokens)

Save or close an open schedule. Never saves on its own — closing with unsaved changes requires either saving first or passing discardChanges=true, so work is never silently lost. Note that no library can author native .mpp; use format='mspdi' for a .xml Microsoft Project opens natively.

Input parameters:

- `discardChanges` (boolean): Allow close to drop unsaved changes. Defaults to false.
- `format` (string): Output format: 'mspdi' (default, .xml), 'mpx', or 'json'.
- `handle` (string, required): Document handle from project_open.
- `keepOpen` (boolean): Keep the handle open after saving. Defaults to true.
- `op` (string): 'save' (write back over the original path), 'save_as' (write to path), or 'close'.
- `path` (string|null): Target path for save_as. Ignored for save and close.

### `schedule_sequence` (~447 tokens)

Recover the logic a schedule is missing by reading the order its own dates already state. A schedule whose work was laid out in the right order but never linked is a bar chart, not a network: nothing moves when anything slips, float reads as enormous, and any target date computed over it is arithmetic. This finds the repeating groups — apartments, floors, spans, wells, whatever the work repeats over — reads the order each one runs in, keeps only the orderings the repetitions agree on, and proposes the missing links. It never invents an order the dates do not state and never proposes a link where a path already exists. Defaults to proposing only; pass apply=true to write them, verified.

Input parameters:

- `apply` (boolean): Write the proposed links instead of only reporting them. Defaults to false.
- `groupBy` (string): 'unit' (default) groups by the identifier that varies between repetitions — the number at the end of a task name. 'parent' groups by the WBS parent instead.
- `groupDepth` (integer): How far down the WBS the grouping branch sits — the tower, phase or building a unit number is unique within. Defaults to 2. Raise it where units repeat within a deeper branch; lower it where one numb…
- `handle` (string, required): Document handle from project_open.
- `maxLinks` (integer): Maximum links to propose in one pass. Defaults to 500.
- `minAgreement` (number): How strongly the repetitions must agree on an ordering before it is trusted, 0-1. Defaults to 0.8. Lower it only where the variation between units is genuine.
- `preserveDates` (boolean): Carry the existing gap between each pair as lag so no date moves. Off by default: it sounds like the safe choice and measurably is not, because it turns every recovered link into a positive lag. On a…

### `project_info` (~69 tokens)

Summarise an open schedule: dates, counts, calendars, which baselines actually hold data, and the aliases of the custom fields. Read this before tasks_query — without the aliases nobody can tell what Text1 means in this particular schedule.

Input parameters:

- `handle` (string, required): Document handle from project_open.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/horizungroup-horizun-msproject-mcp/horizunmsprojectmcp#diagnostics

## Score history

- 2026-09-20: 78
- 2026-09-19: 77
- 2026-09-18: 77
- 2026-09-17: 80
- 2026-09-16: 79
- 2026-09-15: 79
- 2026-09-14: 78
- 2026-09-13: 78
- 2026-09-12: 77
- 2026-09-11: 77
- 2026-09-10: 80
- 2026-09-09: 79
- 2026-09-08: 79
- 2026-09-07: 78
- 2026-09-06: 78
- 2026-09-05: 77
- 2026-09-04: 77
- 2026-09-03: 80
- 2026-09-02: 79
- 2026-09-01: 79
- 2026-08-31: 78
- 2026-08-30: 78
- 2026-08-29: 77
- 2026-08-28: 77
- 2026-08-27: 76
- 2026-08-26: 76
- 2026-08-25: 75
- 2026-08-24: 74
- 2026-08-23: 73
- 2026-08-22: 73

## Common questions

### What is the Microsoft Project MCP server?

Microsoft Project is an MCP server listed in the public MCP registry as io.github.HorizunGroup/horizun-msproject-mcp. Audit, reschedule and author Microsoft Project schedules. No Java, no Project install. This page covers its NuGet package (HorizunMsProjectMcp).

### Is the Microsoft Project MCP server safe to use?

Microsoft Project scores 78 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 20 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Microsoft Project MCP server expose?

Microsoft Project exposes 25 tools: project_health, bim_link, schedule_qa, calendars_write, schedule_update, and 20 more. Their descriptions and schemas cost roughly 5,013 tokens of context every time the server is loaded.

### Is the Microsoft Project MCP server still maintained?

Microsoft Project is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Microsoft Project MCP server under?

Microsoft Project declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- NuGet package: https://www.nuget.org/packages/HorizunMsProjectMcp
- Socket report: https://socket.dev/nuget/package/HorizunMsProjectMcp
- Repository: https://github.com/HorizunGroup/horizun-msproject-mcp
- Changelog RSS feed: https://verifymcp.io/servers/horizungroup-horizun-msproject-mcp/horizunmsprojectmcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/horizungroup-horizun-msproject-mcp/horizunmsprojectmcp.json
- HTML version of this page: https://verifymcp.io/servers/horizungroup-horizun-msproject-mcp/horizunmsprojectmcp
