The claim was true when I wrote it
A sentence in two of my agent contracts described a vendor API accurately — and had been false for ten days. Three readings of one endpoint in three weeks, and where the changelog was actually hiding.
First-hand beats hearsay. That's the rule I thought I was following when I wrote a sentence about a vendor's API into two of my agent contracts, off a probe I'd run myself.
First-hand has a shelf life. Nothing tells you when it's up.
Ten days before I wrote mine, the vendor had shipped the fix that should have made it false. I didn't find that out for three more weeks. Then I corrected it, wrongly, and had to correct the correction. Three readings of one endpoint in three weeks.
What I thought I knew
I built a Jira extraction sub-agent last month. Its job is to make an expensive API call inside a disposable context and hand back only a slim projection, so the fat payload never reaches the main agent's context. The premise underneath it was that you couldn't ask the API for less — the payload was unavoidable at the source, so the only place to shrink it was downstream. The cost side of that, with the token numbers attached, is its own post.
The evidence was a probe on 6 July 2026. Three calls with different fields= and responseContentFormat= filters, byte-identical bundles, hashes to match. First-hand, mine, and — I assumed — settled. I wrote it into the contracts in as many words and stopped thinking about it.
Where the changelog was
The Atlassian MCP connector is a remote, hosted endpoint. There's no version string, just a v1 in a URL path. When a dependency like that changes, there's no local diff, no package bump, nothing in your repo that moves.
What it does have, and what I didn't think to look for, is a public issue tracker. The changelog I wanted was sitting in a closed ticket on it.
Issue #17 ("MCP tool responses too verbose…") was filed in November 2025. On 13 May 2026, jclipa-lightit posted a full test matrix concluding the fields parameter was "currently 100% ignored", with fields:["summary","status"], fields:["summary"] and fields:[] all returning the same payload. On 6 June, CarstVaartjes confirmed it and measured a floor of about 4 KB per issue no matter what you asked for. Then on 26 June, an Atlassian engineer closed the issue: fields now applied on both the single-issue fetch and the JQL search, and the default response cut to a named thirteen-field set.
So that sentence had been an accurate description of this server for months. Two other people had run the same check, eight weeks and one month ahead of me, and published the results where I could have found them. I wasn't imagining the behavior. Whether it was still true on my tenant the day I tested is a different question, and the next paragraph is where it stops having an answer.
That probe was also weaker than I counted it. Of its three calls, two varied only responseContentFormat, and adf-versus-markdown is a distinction this endpoint has a documented history of not honoring — #124 and #189 both report it. So three calls were really two conditions, and only one of them touched fields= at all.
Which leaves that one arm unexplained, and I'm not going to paper over it. My fields= call returned identical bytes ten days after that comment. Either the fix hadn't reached my tenant, or my call was malformed, or something changed back. Two Atlassian infrastructure events landed in that same week and either could be the answer: the /v1/sse transport was sunset on 30 June, and a Rovo MCP v2 preview was announced the same day. If my contracts were still pointed at the old transport, I was plausibly hitting a frozen path. I don't know, and I didn't chase it — I took the byte-identical result at face value. That's the actual mistake, and it's a different one from being out of date.
Trying it properly
Here's the probe I should have run. Same query twice, once with a narrow fields= and once with the parameter omitted, both responses measured and hashed. 28 July 2026, one ticket and one result set, on my employer's Jira instance. Observed, not a benchmark.
Single issue (getJiraIssue, fields=["summary","status"] vs default):
| narrowed | default | |
|---|---|---|
| bytes | 5,973 | 7,410 |
| fields returned | 6 | 13 |
| sha256 | 45af7cba… |
e74cbc37… |
Bulk search (searchJiraIssuesUsingJql, 50 issues, fields=["summary","status","updated","assignee"] vs default):
| narrowed | default | |
|---|---|---|
| bytes | 293,541 | 368,060 |
| fields returned | 7 | 13 |
| sha256 | c3b7c632… |
97799715… |
The hashes differ. The field counts differ. fields= is not ignored.
But I asked for two fields and got six.
A mandatory core
Diff the field lists and it falls out. On the single-issue probe I asked for summary and status and got my two plus four more: description, issuetype, project, assignee. On the bulk probe I asked for four and got seven. (assignee was in that request, so only the single-issue probe can speak to whether it's forced. It is.)
That contradicts the fix. The engineer who closed #17 wrote: "If you pass fields: ["summary", "status"], you get back only those fields instead of the full payload."

Narrowing bought 19.4% on the single issue and 20.2% on the search. It bought so little because the forced core contains the one field that costs anything:
| share of the narrowed payload | |
|---|---|
description, single issue |
39% (2,341 of 5,973 B) |
description, 50-row search |
44% (129,706 of 293,541 B) |
description is the largest line item in a response you already narrowed, and no fields= value I tried removed it. I didn't test exclusion syntax. That's the finding, with that caveat sitting on it: the filter works on everything except the part that matters.
The description problem isn't news to that tracker — CarstVaartjes reported fields:["key"] returning the full description back in June, before the fix. What's new is that it survived the fix, in a release that claimed to close it. I couldn't find another report of that; the issues filed since are about other things. The closing comment on #17 ends "If you still see fields being ignored… open a new issue with the exact tool call", so I did — it's #208. If you're reading this later, that thread will tell you whether any of these numbers still hold.
Wrong twice, right both times
There's a design decision downstream of all this that got the same treatment, and it's the part that changed how I think about the whole business.
The first version of my disk cache wanted a cheap freshness check. Fetch just the issue's updated timestamp, reuse the cached copy if it hasn't moved, no time-based expiry at all. I killed it during design, because the same non-narrowing behavior that justified the extractor also meant you couldn't fetch one field cheaply. I pivoted to a four-hour TTL.
Then a 23 July re-probe said fields= worked, and worked spectacularly — 993 bytes against 7,634 default, an 87% cut. That reading has never reproduced. But at the time it collapsed the reasoning behind the TTL, and I wrote the TTL up as a live design question in a production system, open because of one reading I couldn't reconcile. The same reading told me my extractors were no longer justified.
The forced core closes it. A fields=["updated"] call still returns description, issuetype, project and assignee. On the 28 July probe, narrowing to two fields still left 5,973 bytes of a 7,410-byte default, and swapping summary and status for updated moves that by a few hundred bytes — going off the per-field breakdown from the 23 July reading, which is itself the one I don't trust. So the cheap probe lands somewhere between three-quarters and four-fifths of a full fetch. Not cheap enough to be worth the extra call, not at these ratios.
The original design call was right. The reason I gave for it was wrong, and the replacement reason was also wrong. Three passes at the mechanism, one unchanged decision.
I find that more reassuring than a clean explanation would have been. The decision was load-bearing on something real. The stories I kept attaching to it weren't.
What I still can't tell you
Which failure produced the 23 July reading. Either the server changed between the two probes, or that measurement was wrong when I took it. The arithmetic doesn't settle it, and neither does the tracker.
Issue #124 is the closest thing to a precedent, and it's murkier than I'd like. A reporter found responseContentFormat:"adf" returning markdown, an Atlassian engineer replied the same day that he could not reproduce it, and the next day the reporter retested, found it working, speculated "It seems a server-side update was deployed between then and now", and closed his own issue. Nobody at Atlassian ever confirmed a deploy. So it records a reporter seeing this endpoint behave two different ways a day apart — which is either a silent server change or a client-specific difference, and the thread never resolves which.
Issue #189, filed three months after #124 closed, reports the same endpoint doing the same thing again. It doesn't reference #124, and nobody has called it a regression — it frames the behavior as never having been implemented. That's the shape of the thing, though: a symptom that comes and goes on an endpoint nobody outside Atlassian can version.
On an endpoint with that history, "it changed" and "I measured it wrong" are both ordinary. I'm not going to pick one to make the story cleaner.
The direction of the errors
Everything before the re-probe pointed one way, toward the thing I was already arguing for. Two independent checkers read an earlier draft of the companion post — a stage in how I write these — and the first handed me a GitHub issue as corroboration for the non-narrowing claim while the second read it and found it said nothing of the kind.
Then the 23 July correction over-swung the other way. It told me my extractors were no longer justified, which was also wrong, and would have had me delete working infrastructure over a percentage.
Motivated reasoning is easier to spot than its rebound. Once you've been burned, "I was wrong about this" starts to feel like the rigorous answer regardless of whether it's the true one. Which is why the rule I landed on isn't about being more careful. Care doesn't help — I was careful in both directions and wrong in both.
The rule I run now
When you depend on a remote you cannot version, encode the defense, not the measurement.
Request fields= and project the result down yourself. If the forced core shrinks tomorrow, the projection is redundant. If it grows, the projection absorbs it. It isn't free — a hardcoded projection is a line of code that will silently drop a field the vendor adds later, which is a failure mode my own story would have produced. I'll take that over a claim that expires without telling me. The point is that neither reading of the API, the flattering one or the humbling one, changes what I build. That's what makes it a defense against both directions of error, instead of a better measurement that expires like the last one.
Two things follow from it.
Look for the vendor's changelog wherever it actually lives. For an unversioned hosted endpoint that's often the issue tracker, not a release page. Check both. This repo's releases page is empty; the fix that broke my claim was announced in a closing comment on a seven-month-old issue.
Date every claim about someone else's system, and name the tier that took the reading. The original notes were Sonnet 4.6-era, the 23 July re-probe ran on Sonnet 5, the 28 July paired probe on Opus 5. Whether the tier caused the difference I can't say — three uncontrolled runs can't separate it from the date, the prompt, or how hard I was looking. But three readings, three tiers, three different write-ups is enough to make me record which took the reading.
An undated "the MCP ignores fields=" in an agent contract is a claim with no expiry and no owner. A dated one is a claim you can go re-run. That's the only reason any of this was recoverable.
FAQ
Does the Atlassian MCP server honor fields=?
Partially, on my tenant, as of 28 July 2026. It returns fewer fields than the default, worth about 20% of the payload on both getJiraIssue and searchJiraIssuesUsingJql — but description, issuetype, project and assignee came back whether or not I asked for them, and description is the single heaviest field. Atlassian closed the fields= issue on 26 June 2026 with a comment stating that a narrow request returns only the fields you asked for. There's no release note, so I can't date the deploy — only the comment. Either way that isn't what I measured a month later, and I've filed it as issue #208. The endpoint is remote and unversioned, so treat any of this (mine included) as a dated observation rather than a fact about the service.
How do you find the changelog for a hosted MCP server that has no version string?
Check the vendor's public issue tracker for closed issues, not just open ones. The fix that broke my claim was announced in a closing comment on a seven-month-old issue, with no release note that names the parameter anywhere I could find. Search the tracker for the parameter you depend on, sort by recently closed, and read the maintainer's last comment.